【问题标题】:boolean indexing that can produce a view to a large pandas dataframe?可以生成大型熊猫数据框视图的布尔索引?
【发布时间】:2013-02-28 19:17:19
【问题描述】:

有一个大的数据框,我想对它进行切片(根据多个布尔标准),然后修改这些切片中的条目以更改原始数据框 - 即我需要一个 view 到原始数据框。问题是,花哨的索引总是返回一个copy。想到了.ix 方法,但使用df.ix[] 方法的布尔索引也返回一个副本。

基本上如果df 是我的数据框,我想查看C 列的视图,例如C!=0, A==10, B<30,... 等。在pandas 中有没有快速的方法来做到这一点?

【问题讨论】:

    标签: python dataframe pandas


    【解决方案1】:

    即使df.loc[idx] 可能是df 的一部分的副本,assignment to df.loc[idx] 也会修改df 本身。 (df.ilocdf.ix 也是如此。)

    例如,

    import pandas as pd
    import numpy as np
    df = pd.DataFrame({'A':[9,10]*6,
                       'B':range(23,35),
                       'C':range(-6,6)})
    
    print(df)
    #      A   B  C
    # 0    9  23 -6
    # 1   10  24 -5
    # 2    9  25 -4
    # 3   10  26 -3
    # 4    9  27 -2
    # 5   10  28 -1
    # 6    9  29  0
    # 7   10  30  1
    # 8    9  31  2
    # 9   10  32  3
    # 10   9  33  4
    # 11  10  34  5
    

    这是我们的布尔索引:

    idx = (df['C']!=0) & (df['A']==10) & (df['B']<30)
    

    我们可以通过分配给df.loc[idx, ...] 来修改dfidx 为True 的那些行。例如,

    df.loc[idx, 'A'] += df.loc[idx, 'B'] * df.loc[idx, 'C']
    print(df)
    

    产量

          A   B  C
    0     9  23 -6
    1  -110  24 -5
    2     9  25 -4
    3   -68  26 -3
    4     9  27 -2
    5   -18  28 -1
    6     9  29  0
    7    10  30  1
    8     9  31  2
    9    10  32  3
    10    9  33  4
    11   10  34  5
    

    【讨论】:

    • 谢谢...正是我要找的东西!
    • 当我运行命令 subdf['A'] += subdf['B'] * subdf['C'] 时,它确实会更改值,但我收到以下警告:A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy # Used internally for debug sandbox under external interpreter。然后我尝试遵循此警告subdf.loc[:,'A'] += subdf['B'] * subdf['C'] 中的建议并再次收到相同的警告。什么是正确的?
    • @stvn66:警告是说subdfdf 切片的副本,通常不希望为切片的副本分配新值。例如,如果要使用df[idx]['A'] += df[idx]['B'] + df[idx]['C'],那么df 本身不会改变,因为只有df[idx] 被修改并且df[idx]df 切片的副本。修改副本不会修改原件。在这种情况下,我们将subdf 分配给副本,并且我们想要修改subdf。所以代码正在做我们想做的事情,警告是过分热心的。所以你可以随意忽略警告。
    • @stvn66:如果您不喜欢看到警告,可以使用subdf = df[idx].copy()。然后subdf['A'] += subdf['B'] * subdf['C'] 不会发出警告。然而,这确实执行了不必要的复制。因此,另一种选择是使用pd.options.mode.chained_assignment = None 关闭警告。
    • @stvn66:另一种选择是使用 with warnings.catch_warnings() 在每个实例的基础上抑制警告。
    【解决方案2】:

    pandas 文档有一个关于Returning a view versus a copy 的部分:

    关于何时返回数据视图的规则完全依赖于 NumPy。 当索引操作涉及标签数组或布尔向量时,结果将是一个副本。 使用单个标签/标量索引和切片,例如df.ix[3:6]df.ix[:, 'A'],将返回一个视图。

    【讨论】:

      【解决方案3】:

      基于 unutbu 的示例,您还可以像这样在 df.index 上使用布尔索引:

      In [11]: df.ix[df.index[idx]] = 999
      
      In [12]: df
      Out[12]:
            A    B    C
      0     9   23   -6
      1   999  999  999
      2     9   25   -4
      3   999  999  999
      4     9   27   -2
      5   999  999  999
      6     9   29    0
      7    10   30    1
      8     9   31    2
      9    10   32    3
      10    9   33    4
      11   10   34    5
      

      【讨论】:

        猜你喜欢
        • 2021-03-19
        • 1970-01-01
        • 2021-05-17
        • 1970-01-01
        • 1970-01-01
        • 2013-07-31
        • 1970-01-01
        • 2022-07-10
        • 2020-08-22
        相关资源
        最近更新 更多