如何从CSV文件聚合到Python文件中的值

2024-10-01 09:29:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我在CSV文件中有一个数据集。下面是一个示例:

Time,Location,Companyid,Metrics,Amount

2012Q1,AK_995,A,Sales,8820156.363
2012Q1,AK_995,B,Revenue,28392730.51
2012Q1,AK_995,C,Sales,6980332.166
2012Q1,AK_996,B,Revenue,1894254.13
2012Q1,AK_996,A,Sales,4664103.766
2012Q2,AK_995,C,Sales,7980332.166

这里的time是年份和季度,location是带有ID的状态符号,因此每个状态可以有多行,每个companyid具有不同的ID。我想做的是,对于每个companyid,我想为每个特定的time添加一个特定状态的所有amount。例如,在上面的示例中,companyid1有两条记录time2012Q1-一条记录AK_995,另一条记录AK_996。我想在这两个值中加上amount,把AK作为location,得到一个值为2012Q1,AK,1,13484260.129的记录。对于所有状态,这应该在每个company期间进行。注意,amountstime不应添加,因为上面的示例companyid3有2条记录,它们的状态相同,但时间段不同。另外,我只想在MetricsSales的地方这样做,所以我想删除Metrics不是{}的任何行,并且不要在聚合中添加这些数量。在

我还想将输出写入另一个csv文件。我该怎么做?在

更新部分:

根据@MichaelLaszlo的建议,我有这个代码。代码似乎有一个问题。在输出文件中,我希望将特定companyid的所有记录放在一起。一个companyid中记录的顺序应该是按time的顺序递增(特定位置的记录为特定的companyid聚集在一起)。例如,如果有一个companyidB,那么companyidB的所有记录都应该在一起,顺序如下:

^{pr2}$

如上所示,companyidB的所有记录都在一起,companyidB内,特定{}的记录按time的顺序排列在一起。在我当前的输出中,我得到了所有分散的companyids的记录。我目前的代码是:

totals = {}

# Aggregate sales by quarter, state, and company.
for row in csv.reader(open('data.csv')):
  if row[3] == 'Sales':
    key = (row[0], row[1][:2], row[2])
    totals[key] = totals.setdefault(key, 0) + float(row[4])

# Write aggregated data to file.
with open('aggregated.csv', 'w') as out_file:
  writer = csv.writer(out_file)
  for key, value in totals.items():
    row = list(key) + [value]
    writer.writerow(row)

我当前的示例输出是:

time,state,companyid,amount
2014Q4,AL_,B,547991592.5101689
2014Q1,NV_,B,387534045.40654004
2012Q3,SC_,A,333657617.05835015
2014Q4,DC_,C,54022786.60577
2014Q3,TN_,B,594121931.7221502

如您所见,companyidB的记录是分散的,我希望输出的顺序与我在更新部分中提到的顺序一致。在


Tags: 文件csvkey示例time顺序状态记录
3条回答

我不知道你的数据集有多大,但你应该开始考虑使用熊猫。 您将受益于许多工具,如从csv到按列分组的数据帧创建。 最后你可以灵活地选择输出,而且速度非常快。在

编辑: 抱歉,我现在只有我的手机,但这里是如何从一个csv和生成一个数据帧:http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.from_csv.html 下面是groupby:http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.groupby.html 它看起来像:

import pandas as pd

df = pd.DataFrame.from_csv(r'yourPathToCsv.csv')

data_grouped = df.groupby(['col1','col2'])['colAmount'].sum().to_frame()

然后,可以使用to_csv()函数从Dataframe导出数据。在

更新:现在,read_csv方法优于from_csv方法。下面是一个更新的示例:

^{pr2}$

对于大数据来说,简单但不是最佳选择:

import csv

source = {}
with open('filename.csv', 'rb') as csvfile:
    csvreader = csv.reader(csvfile, delimiter=',', quotechar='"')
    next(csvreader , None) #  skip line
    next(csvreader , None) #  skip line
    for row in csvreader:
        if row[3] != 'Sales':
            continue
        data_date = row[0]
        data_state = row[1].split('_')[0]
        data_company = row[2]
        data_amount = float(row[4])
        if data_date not in source:
            source[data_date] = {}
        if data_state not in source[data_date]:
            source[data_date][data_state] = {}
        if data_company not in source[data_date][data_state]:
            source[data_date][data_state][data_company] = []
        source[data_date][data_state][data_company].append(data_amount)

    for k_date in source:
        for k_state in source[k_date]:
            for k_company in source[k_date][k_state]:
                data = source[k_date][k_state][k_company]
                average = ( sum(data) / len(data) )
                print('%s,%s,%s,%s' % (k_date, k_state, k_company, average))

要聚合数据,请使用哈希。从要聚合的值的元组中生成键。在

totals = {}

for row in csv.reader(open('data.csv')):
  if row[3] == 'Sales':
    key = (row[2], row[1][:2], row[0])
    totals[key] = totals.setdefault(key, 0) + float(row[4])

要写入CSV文件,请在打开的文件对象上使用csv.writer()。要生成行,请将每个哈希键转换为一个列表,并将其与总销售额连接起来。在

^{pr2}$

我们可以将这两个操作组合成一个简短的脚本:

import csv

totals = {}

# Aggregate sales by company, state, and quarter.
for row in csv.reader(open('data.csv')):
  if row[3] == 'Sales':
    key = (row[2], row[1][:2], row[0])
    totals[key] = totals.setdefault(key, 0) + float(row[4])

# Write aggregated data to file.
with open('aggregated.csv', 'w') as out_file:
  writer = csv.writer(out_file)
  for key, value in sorted(totals.items()):
    row = list(key) + [value]
    writer.writerow(row)

运行上面的脚本并检查结果文件aggregated.csv。在

相关问题 更多 >