python - 根据其他数据帧中的列标题成员资格(按日期)在 pandas 数据帧(按日期)中设置 boolean 值

标签 python pandas boolean intersection

我有两个 pandas 数据框(X 和 Y),并尝试根据 X 轴和 Y 的列/成分之间的相互关系用 boolean 值填充第三个(Z)。我只能通过以下方式做到这一点嵌套循环和代码适用于我的玩具示例,但对于我的实际数据集来说太慢了。

# define X, Y and Z
idx=pd.date_range('2016-1-31',periods=3,freq='M')
codes = list('ABCD')
X = np.random.randn(3,4)
X = pd.DataFrame(X,columns=codes,index=idx)

Y = [['A','A','B'],['C','B','C'],['','C','D']]
Y = pd.DataFrame(Y,columns=idx)

Z = pd.DataFrame(columns=X.columns, index=X.index)

正如您所看到的,在此示例中 X 的索引与 Y 的列匹配。在我的真实示例中,Y 的列是 X 索引的子集。

Z 轴与 X 轴匹配。如果 Z 的列标题位于 Y 的列中且标题等于 Z 的索引,我想用 True 填充 Z 的元素。我的工作代码如下:

for r in Y:
    for c in Z:
        Z.loc[r,c] = c in Y[r].values

代码非常干净和简短,但在较大的数据集上运行需要很长时间。我希望有一种矢量化方法可以更快地实现相同的目标。

任何帮助将不胜感激

谢谢!

最佳答案

您可以使用stack方法,其中 DataFrame 的值转换为列,列转换为 DataFrame 的值。上次测试 NaNnotnull :

print (Y.replace({'':np.nan})
        .stack()
        .reset_index(0)
        .set_index(0, append=True)
        .squeeze()
        .unstack()
        .rename_axis(None, axis=1)
        .notnull())

                A      B     C      D
2016-01-31   True  False  True  False
2016-02-29   True   True  True  False
2016-03-31  False   True  True   True

另一个使用pivot的解决方案:

print (Y.replace({'':np.nan})
        .stack()
        .reset_index(name='a')
        .pivot(index='level_1', columns='a', values='level_0')
        .rename_axis(None, axis=1)
        .rename_axis(None)        
        .notnull())

                A      B     C      D
2016-01-31   True  False  True  False
2016-02-29   True   True  True  False
2016-03-31  False   True  True   True

按评论编辑:

使用reindex如果索引是唯一的,则 fillna通过 False:

import pandas as pd
import numpy as np

# define X, Y and Z
idx=pd.date_range('2016-1-31',periods=5,freq='M')
codes = list('ABCD')
X = np.random.randn(5,4)
X = pd.DataFrame(X,columns=codes,index=idx)

Y = [['A','A','B'],['C','B','C'],['','C','D']]
Y = pd.DataFrame(Y,columns=idx[:3])
Z = pd.DataFrame(columns=X.columns, index=X.index)

print (X)
                   A         B         C         D
2016-01-31  0.810348 -0.737780 -0.523869 -0.585772
2016-02-29 -1.126655 -0.494999 -1.388351  0.460340
2016-03-31 -1.578155  0.950643 -1.699921  1.149540
2016-04-30 -2.320711  1.263740 -1.401714  0.090788
2016-05-31  1.218036  0.565395  0.172278  0.288698

print (Y)
  2016-01-31 2016-02-29 2016-03-31
0          A          A          B
1          C          B          C
2                     C          D

print (Z)
              A    B    C    D
2016-01-31  NaN  NaN  NaN  NaN
2016-02-29  NaN  NaN  NaN  NaN
2016-03-31  NaN  NaN  NaN  NaN
2016-04-30  NaN  NaN  NaN  NaN
2016-05-31  NaN  NaN  NaN  NaN
Y1 = Y.replace({'':np.nan})
      .stack()
      .reset_index(name='a')
      .pivot(index='level_1', columns='a', values='level_0')
      .rename_axis(None, axis=1)
      .rename_axis(None)
      .notnull()
print (Y1)
                A      B     C      D
2016-01-31   True  False  True  False
2016-02-29   True   True  True  False
2016-03-31  False   True  True   True

print (Y1.reindex(X.index).fillna(False))
                A      B      C      D
2016-01-31   True  False   True  False
2016-02-29   True   True   True  False
2016-03-31  False   True   True   True
2016-04-30  False  False  False  False
2016-05-31  False  False  False  False

关于python - 根据其他数据帧中的列标题成员资格(按日期)在 pandas 数据帧(按日期)中设置 boolean 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38720745/

相关文章:

pandas - 使用 boolean 检查返回数据框中的列名

r - Data.table 中的多个灵活的逻辑列比较

c# - 为什么同样的 msdn C# 示例程序输出与我的不一样?

python - key 错误 : 'type' while drawing a scatter plot with grouped x axis in Python

python - 在两个 python 脚本之间传递字符串

pandas - 重新索引相当于 Pandas 列标题

python - 如何使用值、索引和列的数组更新 pandas 数据框?

python - python中 Pandas 数据框的矩阵表示

python - 使用 patches.Rectangle 绘制不规则光栅图时避免缓慢循环

python - 在 selenium webdriver python 中选择页面文本