【问题标题】:Setting boolean values in pandas dataframe (by date) based on column header membership in other dataframe (by date)根据其他数据框中的列标题成员资格(按日期)在熊猫数据框中设置布尔值(按日期)
【发布时间】:2016-08-02 12:43:27
【问题描述】:

我有两个 pandas 数据框(X 和 Y),并试图根据 X 的轴和 Y 的列/成分之间的相互关系用布尔值填充第三个 (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

代码非常简洁和简短,但在较大的数据集上运行需要很长时间。我希望有一种矢量化的方法可以更快地达到同样的效果。

任何帮助将不胜感激

谢谢!

【问题讨论】:

    标签: python pandas boolean intersection


    【解决方案1】:

    您可以使用stack 方法,将DataFrame 的值转换为列,将列转换为DataFrames 的值。上次测试NaN by notnull

    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,然后False使用fillna

    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
    

    【讨论】:

    • 谢谢,太好了。还有一个问题是我想强制 Z 具有与 X 相同的轴(Y 的轴是一个子集)。我注意到,如果我在面板中创建 X 和 Z 数据框,这会自动发生,其余元素由 NaN 填充。如果我不使用面板,如何将上面的结果拉伸到与 X 相同的轴?例如,如果 X 在索引中有额外的两行
    猜你喜欢
    • 2018-01-18
    • 2021-08-30
    • 2017-05-16
    • 2022-12-14
    • 2013-06-09
    • 2020-05-05
    • 1970-01-01
    • 2020-10-22
    • 1970-01-01
    相关资源
    最近更新 更多