【问题标题】:Modifying the first line of a DataFrame subject to a condition根据条件修改 DataFrame 的第一行
【发布时间】:2019-05-16 04:18:36
【问题描述】:

我有一个如下所示的数据框

import pandas as pd 
df = pd.DataFrame(data={"ID":[11,12,13,14,25],\
"Name":["Alice","Bob","Charlie", "Dan", "Erin"], "X":[1,0,0,0,0]})

   ID     Name  X
0  11    Alice  1
1  12      Bob  0
2  13  Charlie  0
3  14      Dan  0
4  25     Erin  0

我想选择X为0的第一行,并将值改为1。我试过了

df[df["X"]==0]["X"].iloc[0] = 1

但这似乎根本没有修改数据框df。这对我来说很奇怪,因为我没有收到任何错误消息,并且删除 =1 会产生

>>> df[df["X"]==0]["X"].iloc[0]
 0

正如预期的那样。

我怀疑条件会创建数据帧的副本,因此数据帧 df 根本不会被修改。

实现这一目标的最佳方法是什么

   ID     Name  X
0  11    Alice  1
1  12      Bob  1
2  13  Charlie  0
3  14      Dan  0
4  25     Erin  0

当然,这需要系统地完成,因为我需要迭代这个过程。

非常感谢您的帮助。

【问题讨论】:

    标签: python pandas indexing series


    【解决方案1】:

    我将使用idxmax

    df.loc[df.X.eq(0).idxmax(),'X']=1
    df
    Out[153]: 
       ID     Name  X
    0  11    Alice  1
    1  12      Bob  1
    2  13  Charlie  0
    3  14      Dan  0
    4  25     Erin  0
    

    【讨论】:

    • 非常类似于我要发布的内容:df.loc[df['X'].ne(1).idxmax(), 'X'] = 1
    【解决方案2】:

    使用at / iat 进行标量设置

    出现困难是因为您希望将位置行索引与基于标签列索引混合。选择一个并坚持用于行和列。

    您可以始终使用标签,类似于@Wen's solution,但通过at

    df.at[df['X'].eq(0).idxmax(), 'X'] = 1
    

    或者您可以通过iat定位整数索引:

    df.iat[df['X'].eq(0).values.argmax(), df.columns.get_loc('X')] = 1
    

    两种解决方案产生相同的结果。前者可能更具可读性。

    print(df)
    
       ID     Name  X
    0  11    Alice  1
    1  12      Bob  1
    2  13  Charlie  0
    3  14      Dan  0
    4  25     Erin  0
    

    pd.Series.idxmax / np.argmax 是矢量化的,但不是特别有效。如果效率是一个问题,请参阅Efficiently return the index of the first value satisfying condition in array

    【讨论】:

      猜你喜欢
      • 2016-09-21
      • 1970-01-01
      • 2018-11-29
      • 1970-01-01
      • 2017-11-13
      • 1970-01-01
      • 1970-01-01
      • 2021-03-25
      • 2016-01-18
      相关资源
      最近更新 更多