【问题标题】:Calculating mean of Pandas dataframe in iterations在迭代中计算 Pandas 数据框的平均值
【发布时间】:2014-04-01 11:54:54
【问题描述】:

我有一个像这样的巨大 CSV 文件

代码,持续时间

101、32

205、111

722、33

205、67

722、33

205, 241

现在我正在读取块中的文件,因为文件很大。如何计算每个代码的平均持续时间并将其保存到 CSV 文件?

谢谢

【问题讨论】:

    标签: python file csv file-io pandas


    【解决方案1】:

    您可以按代码分组并存储'Code','Duration'的计数和总和;像这样:

    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')
    

    终端输出:

          count  sum         avg
    Code                        
    101       1   32   32.000000
    205       3  419  139.666667
    722       2   66   33.000000
    

    avg_codes.csv文件中的输出:

    Code,avg
    101,32.0
    205,139.66666666666666
    722,33.0
    

    【讨论】:

    • 我得到异常 TypeError: unsupported operand type(s) for +: 'float' and 'str' where code is import pandas as pd import numpy as np from pandas import * from numpy.random import randn def f(g): return pd.DataFrame({'count': [g.shape[0]], 'sum': [g['Duration'].sum()]}) reader = pd.read_csv(" Sample.csv", iterator=True,chunksize=1000, usecols=[1,5]) acc = pd.DataFrame({}) for chunk in reader: acc = acc.add(chunk.groupby('To'). apply(f).reset_index(level=1,drop=True),fill_value=0) acc['avg'] = acc['sum']/acc['count'] print acc
    【解决方案2】:

    不是pandas,但它可以工作并且内存效率很高。

    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}
    

    【讨论】:

      【解决方案3】:

      对每个数据帧使用groupby.sizegroupby.sum,然后将它们归约为结果:

      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)
      

      您也可以在最后一步使用以下代码:

      r3 = pd.concat(sums, axis=1).sum(axis=1) / pd.concat(counts, axis=1).sum(axis=1).astype(float)
      

      检查结果:

      print np.allclose(r1, r2)
      print np.allclose(r1, r3)
      

      【讨论】:

        猜你喜欢
        • 2017-07-07
        • 1970-01-01
        • 1970-01-01
        • 2016-02-12
        • 2017-02-16
        • 1970-01-01
        • 2020-07-09
        • 2022-08-17
        • 2019-12-03
        相关资源
        最近更新 更多