Reputation: 23
I have a huge CSV file like this
Code, Duration
101, 32
205, 111
722, 33
205, 67
722, 33
205, 241
Now I am reading file in chunk as file is pretty big. How to calculate avg duration for each code and save it to CSV file?
Thanks
Upvotes: 0
Views: 267
Reputation: 17475
You can group by code and store the count and sum of 'Code'
,'Duration'
; something like this:
import pandas as pd
def f(g):
return pd.DataFrame({'count': [g.shape[0]], 'sum': [g['Duration'].sum()]})
reader = pd.read_csv('data.csv',chunksize=2)
acc = pd.DataFrame({})
for chunk in reader:
acc = acc.add(chunk.groupby('Code').apply(f).reset_index(level=1,drop=True),fill_value=0)
acc['avg'] = acc['sum']/acc['count']
print acc
acc.to_csv('avg_codes.csv',cols=['avg'],index_label='Code')
Output in terminal:
count sum avg
Code
101 1 32 32.000000
205 3 419 139.666667
722 2 66 33.000000
Output in file avg_codes.csv:
Code,avg
101,32.0
205,139.66666666666666
722,33.0
Upvotes: 1
Reputation: 97331
use groupby.size
and groupby.sum
for every dataframe, and then reduce them to the result:
import numpy as np
import pandas as pd
c = np.random.randint(100, 10000, 100000)
d = np.random.rand(100000)
df = pd.DataFrame({"c":c, "d":d})
r1 = df.groupby("c").d.mean()
counts = []
sums = []
for i in range(10):
df2 = df[i*10000:(i+1)*10000]
g = df2.groupby("c").d
counts.append(g.size())
sums.append(g.sum())
from functools import partial
func = partial(pd.Series.add, fill_value=0)
r2 = reduce(func, sums) / reduce(func, counts).astype(float)
You can also use following code for the final step:
r3 = pd.concat(sums, axis=1).sum(axis=1) / pd.concat(counts, axis=1).sum(axis=1).astype(float)
to check the result:
print np.allclose(r1, r2)
print np.allclose(r1, r3)
Upvotes: 1
Reputation: 45552
Not pandas
but it works and is memory efficient.
import csv
from collections defaultdict
code_counts = defaultdict(int)
code_durations = defaultdict(int)
with open('yourfile.csv', 'rb') as f:
reader = csv.reader(f)
next(reader) # discard header row
for code, duration in reader:
code_counts[code] += 1
code_durations[code] += int(duration)
code_averages = {code: code_duratons[code] / float(code_counts[code]) for code in code_counts}
Upvotes: 1