【问题标题】:loop through a pandas data frame to replace existing values using for loop循环遍历 pandas 数据框以使用 for 循环替换现有值
【发布时间】:2020-03-01 03:54:52
【问题描述】:

问题:我正在尝试使用 for 循环逐行遍历数据框。但它没有按预期工作。我知道有 iterrows() 和 itertuple() 我想试验 for 循环。

你能告诉我这是哪里出错了吗?

样本数据

data3 = {"one":['101', '102', '103' , '104'],
     "two":['101', '105', '106', '104'],
     "three": ['102', '5', '107', '108'],
     "other": ['101', '102', '103' , '104']
     }
df3 = pd.DataFrame(data3)

目标:逐行检查“二”列,以及“一”列中是否存在“二”列的值 然后创建一个值为“del”的新列“new_col”。如果“一”列中不存在该值,则 将“new_col”创建为“keep”。例如,如果“二”列有 101,我想将它与“一”列的所有值进行比较

我的代码:

dfToList1 = df3['two'].tolist()
for x in dfToList1:
   if x in df3['one'].values:
       df3['new_col'] = 'del'
   else:
       df3['new_col'] = 'keep'

然后我可以用类似'none'的字符串替换'two'中与'one'匹配的值

df3.loc[df3['new_col'] == 'del', 'two'] = 'none'

我的输出:

理想情况下,在第 2 行和第 3 行,“two”中的 5 和 107 不包含在“one”中,因此第 2 行和第 3 行中的 new_col 应该具有值“keep”,但我没有得到它。

    one other   three   two new_col
0   101 101     102     101     del
1   102 102       5     105     del
2   103 103     107     106     del
3   104 104     108     104     del

预期输出

    one other   three   two  new_col
0   101 101     102     101     del
1   102 102       5     105     keep
2   103 103     107     106     keep
3   104 104     108     104     del

【问题讨论】:

  • 您的目标与您的预期输出不符。您说您希望 new_col 成为 del 或 keep 但您的预期输出还有其他内容。你能澄清一下吗?
  • 你是对的。按要求更新。

标签: python pandas for-loop


【解决方案1】:

使用np.where 与Series.eq 和Series.isin 进行检查。

df3['newcol']=np.where(~df3.two.isin(df3.one),'keep','del')

或按列“一”与第二列的任何共同值进行选择:

df3['newcol']=np.where(~df3.one.isin(df3.loc[df3.two.eq(df3.one),'two']),'keep','del')
print(df3)

   one  two three other newcol
0  101  101   102   101    del
1  102  105     5   102   keep
2  103  106   107   103   keep
3  104  104   108   104    del

详情

two_coincident_one=df3.loc[df3.two.eq(df3.one),'two']
print(two_coincident_one)
0    101
3    104
Name: two, dtype: object


~df3.one.isin(two_coincident_one)

0    False
1     True
2     True
3    False
Name: one, dtype: bool

【讨论】:

  • 这很好用。你能否给我一点提示,这个比 df3['newcol']=np.where(~df3.two.isin(df4.one),'keep','del') 之前建议的那个更好。
  • 只需使用Series.eq,就会在两列之间选择匹配的行。用DataFrame.loc,选择与第1列重合的'two'列的行。然后用Series.isin,选择前面选择的第1列的值(见详情)
  • 虽然使用上述方法,您只选择了第 2 列中其值存在于第 1 列中的行
【解决方案2】:

使用np.where:

df3['new_col'] = np.where(df3['two'].isin(df3['one']), 'del', 'keep')

结果:

   one  two three new_col
0  101  101   102     del
1  102  105     5    keep
2  103  106   107    keep
3  104  104   108     del

【讨论】:

  • 我的错。有用。我试过 np.where() 但没有使用 .isin()
  • 如果这对您有用,请考虑将其标记为答案
猜你喜欢
  • 2021-02-26
  • 2022-01-20
  • 2018-05-30
  • 2016-04-25
  • 2021-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多