加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 添加数据帧并根据可用性划分结果

发布时间:2020-12-20 12:34:35 所属栏目:Python 来源:网络整理
导读:我想添加两个数据帧,我可以通过添加函数来实现. 现在,我想根据初始数据帧(df1,df2,df3)中是否存在相应的值来划分结果数据帧的每个值.例如. df1 = pd.DataFrame([[1,2],[3,4]],index =['A','B'],columns = ['C','D'])df2 = pd.DataFrame([[11,12],[13,14]],in
我想添加两个数据帧,我可以通过添加函数来实现.
现在,我想根据初始数据帧(df1,df2,df3)中是否存在相应的值来划分结果数据帧的每个值.例如.

df1 = pd.DataFrame([[1,2],[3,4]],index =['A','B'],columns = ['C','D'])
df2 = pd.DataFrame([[11,12],[13,14]],index = ['A',columns = ['D','E'])
df3 = df1.add(df2,fill_value=0)

这会导致像df一样

C   D     E
A  1.0  13  12.0
B  3.0  17  14.0

我需要一个df,如:

C    D     E
A  1.0  6.5  12.0
B  3.0  8.5  14.0

因为在两个数据帧中都找到了D列,所以我将这些值除以2.
任何人都可以提供一个通用的解决方案,假设我需要添加2个以上的数据帧(因此分割因子也会改变)并且每个数据帧中有超过100列.

解决方法

我们可以在一个步骤中水平连接所有DF:

In [13]: df = pd.concat([df1,df2],axis=1).fillna(0)

这会产生:

In [15]: df
Out[15]:
   C  D   D   E
A  1  2  11  12
B  3  4  13  14

现在我们可以按列分组,计算平均值(平均值):

In [14]: df.groupby(df.columns,axis=1).mean()
Out[14]:
     C    D     E
A  1.0  6.5  12.0
B  3.0  8.5  14.0

或者我们可以一步完成(感谢@jezrael):

In [60]: pd.concat([df1,axis=1).fillna(0).groupby(level=0,axis=1).mean()
Out[60]:
     C    D     E
A  1.0  6.5  12.0
B  3.0  8.5  14.0

定时:

In [38]: df1 = pd.concat([df1] * 10**5,ignore_index=True)

In [39]: df2 = pd.concat([df2] * 10**5,ignore_index=True)

In [40]: %%timeit
    ...: df = pd.concat([df1,axis=1).fillna(0)
    ...: df.groupby(df.columns,axis=1).mean()
    ...:
63.4 ms ± 2.39 ms per loop (mean ± std. dev. of 7 runs,10 loops each)

In [41]: %%timeit
    ...: s = pd.Series(np.concatenate([df1.columns,df2.columns])).value_counts()
    ...: df1.add(df2,fill_value=0).div(s)
    ...:
28.7 ms ± 712 μs per loop (mean ± std. dev. of 7 runs,1 loop each)

In [42]: %%timeit
    ...: pd.concat([df1,df2]).mean(level = 0)
    ...:
65.5 ms ± 555 μs per loop (mean ± std. dev. of 7 runs,10 loops each)

In [43]: df1.shape
Out[43]: (200000,2)

In [44]: df2.shape
Out[44]: (200000,2)

目前的获胜者:@jezrael(28.7 ms±712μs) – 恭喜!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读