【问题标题】:Complex row and column Manipulations pandas复杂的行和列操作 pandas
【发布时间】:2015-09-13 19:41:00
【问题描述】:

我正在尝试同时执行行和列操作。我有时间序列的数据。我确实检查了此处和文档中的几乎所有示例,但运气不佳,并且比以前更加困惑。

我有两个文件都在同一个路径

Path = '/'

File_1.csv 

Nos,00:00:00,12:00:00
123,5245,624
125,4534,65
567,642,7522


File_2.csv
Nos,00:00:00
123,20
123,20
123,20
125,50
125,50
567,500
567,500
567,500
567,500
567,500

预期的输出是将file_1.csvcol[last] 计数合并为file_2.csv 作为新列,同时执行以下操作:

  1. Nos=123 的值,它在file_2.csv 中出现3 次,因此除以相应的值,即624/3 = 208

  2. 现在通过将与Nos 对应的同一行中的00:00:00 的值添加到新列中来放置这个新值,该新列将具有来自file_1.csv 的标题col[last]。即208+20=228

现在附加的file_2.csv 看起来像:

File_2.csv
    Nos,00:00:00,12:00:00
    123,20,228
    123,20,228
    123,20,228
    125,50,82/83 #float to be rounded off
    125,50,82/83
    567,500,2004 #float rounded off
    567,500,2004
    567,500,2004
    567,500,2004
    567,500,2004

这看起来超级复杂,从哪里开始理解。任何关于编写代码的建议都会有很大的帮助。提前致谢。

【问题讨论】:

    标签: python file csv pandas time-series


    【解决方案1】:

    将两个数据框合并为一个:

    In [34]: df3 = pd.merge(df2, df1[['Nos', '12:00:00']], on=['Nos'], how='left')
    
    In [35]: df3
    Out[35]: 
       Nos  00:00:00  12:00:00
    0  123        20       624
    1  123        20       624
    2  123        20       624
    3  125        50        65
    4  125        50        65
    5  567       500      7522
    6  567       500      7522
    7  567       500      7522
    8  567       500      7522
    9  567       500      7522
    

    然后您可以执行groupby/transform 来计算每个组中有多少项目:

    count = df3.groupby(['Nos'])['12:00:00'].transform('count')
    

    然后您希望计算的值可以表示为

    df3['12:00:00'] = df3['00:00:00'] + df3['12:00:00']/count 
    

    例如,

    import pandas as pd
    df1 = pd.read_csv('File_1.csv')
    df2 = pd.read_csv('File_2.csv')
    
    last1, last2 = df1.columns[-1], df2.columns[-1]
    df3 = pd.merge(df2, df1[['Nos', last1]], on=['Nos'], how='left')
    
    count = df3.groupby(['Nos'])[last1].transform('count')
    df3[last1] = df3[last2] + df3[last1]/count 
    print(df3)
    

    产量

       Nos  00:00:00  12:00:00
    0  123        20     228.0
    1  123        20     228.0
    2  123        20     228.0
    3  125        50      82.5
    4  125        50      82.5
    5  567       500    2004.4
    6  567       500    2004.4
    7  567       500    2004.4
    8  567       500    2004.4
    9  567       500    2004.4
    

    或者,您可以使用

    df3[last1] = df3.groupby(['Nos']).apply(lambda x: x[last2] + x[last1]/len(x) ).values
    

    而不是

    count = df3.groupby(['Nos'])[last1].transform('count')
    df3[last1] = df3[last2] + df3[last1]/count 
    

    但是,由于 groupby/apply 对每个组进行一次加法和除法,因此速度较慢,而

    df3[last1] = df3[last2] + df3[last1]/count 
    

    正在对整列执行加法和除法。如果有很多组,性能差异可能会很大。将两个数据帧合并为一个:

    In [34]: df3 = pd.merge(df2, df1[['Nos', '12:00:00']], on=['Nos'], how='left')
    
    In [35]: df3
    Out[35]: 
       Nos  00:00:00  12:00:00
    0  123        20       624
    1  123        20       624
    2  123        20       624
    3  125        50        65
    4  125        50        65
    5  567       500      7522
    6  567       500      7522
    7  567       500      7522
    8  567       500      7522
    9  567       500      7522
    

    然后您可以执行groupby/transform 来计算每个组中有多少项目:

    count = df3.groupby(['Nos'])['12:00:00'].transform('count')
    

    然后您希望计算的值可以表示为

    df3['12:00:00'] = df3['00:00:00'] + df3['12:00:00']/count 
    

    例如,

    import pandas as pd
    df1 = pd.read_csv('File_1.csv')
    df2 = pd.read_csv('File_2.csv')
    
    last1, last2 = df1.columns[-1], df2.columns[-1]
    df3 = pd.merge(df2, df1[['Nos', last1]], on=['Nos'], how='left')
    
    count = df3.groupby(['Nos'])[last1].transform('count')
    df3[last1] = df3[last2] + df3[last1]/count 
    print(df3)
    

    产量

       Nos  00:00:00  12:00:00
    0  123        20     228.0
    1  123        20     228.0
    2  123        20     228.0
    3  125        50      82.5
    4  125        50      82.5
    5  567       500    2004.4
    6  567       500    2004.4
    7  567       500    2004.4
    8  567       500    2004.4
    9  567       500    2004.4
    

    或者,您可以使用

    df3[last1] = df3.groupby(['Nos']).apply(lambda x: x[last2] + x[last1]/len(x) ).values
    

    而不是

    count = df3.groupby(['Nos'])[last1].transform('count')
    df3[last1] = df3[last2] + df3[last1]/count 
    

    但是,由于groupby/apply 对每个组进行一次加法和除法,因此速度较慢,而

    df3[last1] = df3[last2] + df3[last1]/count 
    

    正在对整列执行加法和除法。如果有很多组,则性能差异可能很大:

    In [52]: df3 = pd.concat([df3]*1000)
    In [56]: df3['Nos'] = np.random.randint(1000, size=len(df3))
    
    In [57]: %timeit using_transform(df3)
    100 loops, best of 3: 6.49 ms per loop
    
    In [58]: %timeit using_apply(df3)
    1 loops, best of 3: 270 ms per loop
    

    【讨论】:

    • 哇..你应该是用更简单的术语解释的最好老师..谢谢!
    • 上面的程序没有找到这个00:00:00Traceback (most recent call last): File "main_lac_site.py", line 11, in <module> count = df3.groupby(['Ids'])[last1].transform('count') File "/usr/lib/pymodules/python2.7/pandas/core/groupby.py", line 3159, in __getitem__ raise KeyError("Column not found: %s" % key) KeyError: 'Column not found: 00:00:00'
    • 您的真实file_1.csvfile_2.csv 与问题中发布的导致代码在您的真实数据上失败的内容相比肯定存在一些差异。
    • 我使用的数据与问题中显示的相同。
    • df3.columnslast1 返回什么?
    猜你喜欢
    • 2016-11-17
    • 1970-01-01
    • 2014-01-05
    • 2020-05-01
    • 1970-01-01
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多