Pandas - 根据没有 for 循环的条件从返回的子集中编辑单个数据帧值

时间:2021-03-05 15:26:23

标签: python pandas dataframe indexing subset

正如标题所说,请考虑下面的 for 循环示例。 'df' 是一个多行多列的数据框:

for index, row in df.iterrows():
  if row[3] == condition_a and row[4] == condition_b:
    df.at[index, 0] = value_1
    df.at[index, 1] = value_2
    break

这很好用并且可以完成工作。 (我知道你不应该在循环内编辑数据帧......)但是我想知道我是否可以做得更好,因为整个循环已经在父循环内。

问题是我只想编辑返回子集的第一个行,而不是整个子集。这就是循环内的“中断”的原因。

我尝试执行以下操作:

df.loc[(df[3] == condition_a) & (df[4] == condition_b), 0].iloc[0] = value_1
# plus another line to change pos 1 to value_2

虽然这不会导致任何错误,但它也不会分配任何内容(在 df 中没有任何更改)。我希望避免创建一个新的临时数据帧来编辑值,然后与原始 df 合并。这不会比循环慢吗?

所以问题是:这可以完成还是循环是这里唯一的解决方案?在此先感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

您可以获得满足条件的最小索引并使用它来设置新值:

ix = df[(df.iloc[:,3] == condition_a)&(df.iloc[:,4]==condition_b)].index.min()
df.loc[ix, df.columns[[0, 1]]] = [value_1, value_2]

答案 1 :(得分:1)

我认为@Serge Ballesta 的答案就足够了,但前提是索引已排序。

如果不是这样,我建议

condition = (df.loc[:,3] == condition_a) & (df.loc[:,4] == condition_b)
ix = df[condition].index[0]
df.loc[ix, 0] = value_1
df.loc[ix, 1] = value_2

也可以使用字符串而不是整数作为列名,以避免与索引混淆