【问题标题】:Pandas, map two dataframes, count based on condition熊猫,映射两个数据框,根据条件计数
【发布时间】:2016-12-30 12:05:41
【问题描述】:

我编写了一些代码来映射两个数据帧的 id,如果条件匹配,则在现有数据帧的指定列中创建一个计数,我正在寻找一种更有效的计算方法。

样本数据

import numpy as np
import pandas as pd
d = {'ID' : pd.Series([111, 222, 111, 444, 222, 111]), 'Tag' : pd.Series([1, 2, 3, 1, 2, 1])}
df1 = (pd.DataFrame(d))
print(df1) 

    ID  Tag
0  111    1
1  222    2
2  111    3
3  444    1
4  222    2
5  111    1

d = {'ID' : pd.Series([111, 444, 666, 444, 777])}
df2 = (pd.DataFrame(d))
print(df2)    
    ID
0  111
1  444
2  666
3  444
4  777

df2['tag1'] = 0
df2['tag2'] = 0
df2['tag3'] = 0
​
for index, row in df2.iterrows():
    for i, t in df1.iterrows():
        if row['ID'] == t['ID']:
            if t['Tag'] == 1:
                df2.loc[index]["tag1"] += 1
            elif t['Tag'] == 2:
                df2.loc[index]["tag2"] += 1
            elif t['Tag'] == 3:
                df2.loc[index]["tag3"] += 1

输出

print(df2)
    ID  tag1  tag2  tag3
0  111     2     0     1
1  444     1     0     0
2  666     0     0     0
3  444     1     0     0
4  777     0     0     0

比迭代计算最有效的方法是什么?

注意,df1 可以多次包含样本ID,而Tag 的值不同

(df1 和 df2 是大数据帧,df1 有 50,000 行,df2 有 15,000 行)

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    您可以将crosstabmerge 一起使用:

    print (pd.crosstab(df1.ID, df1.Tag))   
    Tag  1  2  3
    ID          
    111  2  0  1
    222  0  2  0
    444  1  0  0
    
    print (pd.merge(df2, pd.crosstab(df1.ID, df1.Tag)
                           .add_prefix('tag')
                           .reset_index(), on='ID', how='left')
             .fillna(0)
             .astype(int))  
    
        ID  tag1  tag2  tag3
    0  111     2     0     1
    1  444     1     0     0
    2  666     0     0     0
    3  444     1     0     0
    4  777     0     0     0
    

    您可以将groupbysizeunstack 一起使用,而不是unstack

    print (df1.groupby(['ID', 'Tag'])['Tag'].size().unstack())   
    Tag    1    2    3
    ID                
    111  2.0  NaN  1.0
    222  NaN  2.0  NaN
    444  1.0  NaN  NaN
    
    print (pd.merge(df2, df1.groupby(['ID', 'Tag'])['Tag'].size().unstack()
                            .add_prefix('tag')
                            .reset_index(), on='ID', how='left')
             .fillna(0)
             .astype(int))  
    
        ID  tag1  tag2  tag3
    0  111     2     0     1
    1  444     1     0     0
    2  666     0     0     0
    3  444     1     0     0
    4  777     0     0     0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-07
      • 2019-05-02
      • 2019-11-15
      • 1970-01-01
      • 2017-08-21
      • 2021-12-28
      • 1970-01-01
      相关资源
      最近更新 更多