我可以使用列表理解方式有条件地更新 pandas 数据框列中的值吗
can i use list comprehension way to conditionally update values in pandas dataframe column
我将行附加到数据框,并且有一个 id 列需要根据 DataFrame 中的现有值是唯一的。
对于新行,我想添加一个 ID。
这里是示例起始数据(新添加的第 2 行和第 3 行)
name
id
0
A
65
1
F
33
2
H
0
3
V
0
数据没有顺序,之前分配的 ID 可能不是连续的。我只想从最高 ID 开始,然后从那里递增。
name
id
0
A
65
1
F
33
2
H
66
3
V
67
我已经实现如下
max_id = df[id_field].max()
for i in df.index:
if df.at[i, id_field] == 0:
max_id += 1
df.at[i, id_field] = max_id
我不得不这样做,因为我无法更新理解中的 max_id
。这感觉不太 python 像。我能以更优雅的方式做到这一点吗?使用 lambda 表达式或推导式?
谢谢
在您的情况下,我们可能需要使用 groupby
和 cumcount
来获得增量,而 cummax
获得最大值
x = df.id.ne(0).cumsum()
df.loc[df.id==0,'id'] = df.id.cummax() + x.groupby(x).cumcount()
df
Out[561]:
name id
0 A 65
1 F 33
2 H 66
3 V 67
这是一个使用 factorize
的想法:
# identify values to replace
m = df['id'].eq(0)
# compute a factor and add the max + 1
df.loc[m, 'id'] = df.loc[m, 'name'].factorize()[0]+df['id'].max()+1
或使用cumsum
:
# identify values to replace
m = df['id'].eq(0)
# replace by max + cumsum of boolean
df.loc[m, 'id'] = df['id'].max()+m.cumsum()
输出:
name id
0 A 65
1 F 33
2 H 66
3 V 67
海象运算符将允许您在理解中更新 max_id
:
import pandas as pd
df = pd.DataFrame({'name':["A","F","H","V"], 'id':[65,33,0,0]})
print(df)
max_id = df['id'].max()
df.loc[df['id'] == 0, 'id'] = [(max_id := max_id + 1) for _ in range(sum(df['id']==0))]
print(df)
输出:
name id
0 A 65
1 F 33
2 H 0
3 V 0
name id
0 A 65
1 F 33
2 H 66
3 V 67
我将行附加到数据框,并且有一个 id 列需要根据 DataFrame 中的现有值是唯一的。
对于新行,我想添加一个 ID。
这里是示例起始数据(新添加的第 2 行和第 3 行)
name | id | |
---|---|---|
0 | A | 65 |
1 | F | 33 |
2 | H | 0 |
3 | V | 0 |
数据没有顺序,之前分配的 ID 可能不是连续的。我只想从最高 ID 开始,然后从那里递增。
name | id | |
---|---|---|
0 | A | 65 |
1 | F | 33 |
2 | H | 66 |
3 | V | 67 |
我已经实现如下
max_id = df[id_field].max()
for i in df.index:
if df.at[i, id_field] == 0:
max_id += 1
df.at[i, id_field] = max_id
我不得不这样做,因为我无法更新理解中的 max_id
。这感觉不太 python 像。我能以更优雅的方式做到这一点吗?使用 lambda 表达式或推导式?
谢谢
在您的情况下,我们可能需要使用 groupby
和 cumcount
来获得增量,而 cummax
获得最大值
x = df.id.ne(0).cumsum()
df.loc[df.id==0,'id'] = df.id.cummax() + x.groupby(x).cumcount()
df
Out[561]:
name id
0 A 65
1 F 33
2 H 66
3 V 67
这是一个使用 factorize
的想法:
# identify values to replace
m = df['id'].eq(0)
# compute a factor and add the max + 1
df.loc[m, 'id'] = df.loc[m, 'name'].factorize()[0]+df['id'].max()+1
或使用cumsum
:
# identify values to replace
m = df['id'].eq(0)
# replace by max + cumsum of boolean
df.loc[m, 'id'] = df['id'].max()+m.cumsum()
输出:
name id
0 A 65
1 F 33
2 H 66
3 V 67
海象运算符将允许您在理解中更新 max_id
:
import pandas as pd
df = pd.DataFrame({'name':["A","F","H","V"], 'id':[65,33,0,0]})
print(df)
max_id = df['id'].max()
df.loc[df['id'] == 0, 'id'] = [(max_id := max_id + 1) for _ in range(sum(df['id']==0))]
print(df)
输出:
name id
0 A 65
1 F 33
2 H 0
3 V 0
name id
0 A 65
1 F 33
2 H 66
3 V 67