如何在Pandas数据框中选定某些行并集体设置多个列的值?

4

我有一个数据框 df,它有'TPrice'、'THigh'、'TLow'、'TOpen'、'TClose'和'TPCLOSE'列,现在我想将'TPrice'、'THigh'、'TLow'、'TOpen'、'TClose'列的值设置为与'TPCLOSE'列相同的值,对于那些'TPrice'列值为零的行。

展示一些'TPrice'为0的行:

>>> df[df['TPrice']==0][['TPrice','THigh','TLow','TOpen','TClose','TPCLOSE']][0:5]
    TPrice  THigh  TLow  TOpen  TClose  TPCLOSE
13       0      0     0      0       0     4.19
19       0      0     0      0       0     7.74
32       0      0     0      0       0     3.27
43       0      0     0      0       0    12.98
60       0      0     0      0       0     7.48

然后是任务分配:
>>> df[df['TPrice']==0][['TPrice','THigh','TLow','TOpen','TClose']] = df['TPCLOSE']

但是Pandas实际上并没有改变df,因为以下代码仍然可以找到一些行:
>>> df[df['TPrice']==0][['TPrice','THigh','TLow','TOpen','TClose','TPCLOSE']][0:5]
    TPrice  THigh  TLow  TOpen  TClose  TPCLOSE
13       0      0     0      0       0     4.19
19       0      0     0      0       0     7.74
32       0      0     0      0       0     3.27
43       0      0     0      0       0    12.98
60       0      0     0      0       0     7.48

所以怎么做呢?更新Jeff的解决方案:
>>> quote_df = get_quote()
>>> quote_df[quote_df['TPrice']==0][['TPrice','THigh','TLow','TOpen','TClose','TPCLOSE','RT','TVol']][0:5]
    TPrice  THigh  TLow  TOpen  TClose  TPCLOSE   RT  TVol
13       0      0     0      0       0     4.19 -100     0
32       0      0     0      0       0     3.27 -100     0
43       0      0     0      0       0    12.98 -100     0
45       0      0     0      0       0    26.74 -100     0
60       0      0     0      0       0     7.48 -100     0
>>> row_selection = quote_df['TPrice']==0
>>> col_selection = ['THigh','TLow','TOpen','TClose']
>>> for col in col_selection:
...     quote_df.loc[row_selection, col] = quote_df['TPCLOSE']
... 
>>> quote_df[quote_df['TPrice']==0][['TPrice','THigh','TLow','TOpen','TClose','TPCLOSE','RT','TVol']][0:5]
    TPrice  THigh  TLow  TOpen  TClose  TPCLOSE   RT  TVol
13       0   4.19  4.19   4.19    4.19     4.19 -100     0
32       0   4.19  4.19   4.19    4.19     3.27 -100     0
43       0   4.19  4.19   4.19    4.19    12.98 -100     0
45       0   4.19  4.19   4.19    4.19    26.74 -100     0
60       0   4.19  4.19   4.19    4.19     7.48 -100     0
>>> 

1
你正在进行链式赋值,因此修改的是副本,请参见这里;尝试使用df.loc[rows_selector,columns_selector] = ... - Jeff
我尝试执行以下代码:df.loc[df['TPrice']==0,['THigh','TLow','TOpen','TClose']] = df['TPCLOSE'],但是TLow、TOpen和TClose的值与TPCLOSE不同。 - bigbug
2个回答

4

这个操作不会自动广播,因此您需要像这样做

In [17]: df = DataFrame(dict(A = [1,2,0,0,0],B=[0,0,0,10,11],C=[3,4,5,6,7]))

In [18]: df
Out[18]: 
   A   B  C
0  1   0  3
1  2   0  4
2  0   0  5
3  0  10  6
4  0  11  7

首先计算需要屏蔽的行(否则它们可能会在你进行修改 A 的过程中发生改变)

In [19]: mask = df['A'] == 0

In [20]: for col in ['A','B']:
   ....:     df.loc[mask,col] = df['C']
   ....:     

In [21]: df
Out[21]: 
   A  B  C
0  1  0  3
1  2  0  4
2  5  5  5
3  6  6  6
4  7  7  7

这需要进行改变,使其更加自然(因为你正在将rhs上的系列分配给lhs上的数据帧,目前它并没有像你认为的那样广播)。https://github.com/pydata/pandas/issues/5206

我按照您的方法操作,但是数据框只复制了单个值4.19到所有单元格,而不是一系列的值,请参考"Update for Jeff solution"(http://yunpan.cn/Qb2kAabL27DtB)。不知道为什么。(Pandas 0.11.0) - bigbug
你需要 0.12 和 0.11 这样的东西用来修复它们。 - Jeff
好的。0.13版本已经发布,我将进行升级。谢谢。现在我必须逐个设置:row_selection = quote_df['TPrice']==0;value_set = quote_df['TPCLOSE'];quote_df.TOpen[row_selection] = value_set;quote_df.THigh[row_selection] = value_set。 - bigbug

1
>>> import pandas as pd
>>> test=pd.DataFrame({'A': [0,1,2], 'B': [3,4,5], 'C': [6,7,8]})
>>> test
   A  B  C
0  0  3  6
1  1  4  7
2  2  5  8
>>> test.apply(lambda x: x.where(test.A!=0, test.C), axis=0)
   A  B  C
0  6  6  6
1  1  4  7
2  2  5  8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接