如果与列表匹配,则重新移动 Nan 值列数据框
Reshift Nan values column dataframe if match with list
我想重新排列包含 Nan 的列名称值。
我想要的条件是,如果列表中的字符串与列 [1] 匹配,它只会重新移动包含匹配字符串下的行的列值,因此它是我移动前的数据框。
[in] : df
[Out]:
column1 column2 column3
0 aba abab 800.0 900.0
1 aaa acc 900.0 60.0
2 bba jka 809.0 400.0
3 fff yy 521.0 490.0
4 hkm asa j 290.0 321.0
5 daa rr oo 88.0 Nan
6 jtuy ww ddw Nan 600.0
8 bkam ftf Nan Nan
9 fgqefc Nan Nan
10 daas we fg Nan Nan
11 judv mm mk Nan Nan
12 hus gg hhh Nan Nan
这是我的列表
my_list= ['bba jka', 'hkm asa j']
所以这是我想要的数据框,名称是 df1
column1 column2 column3
0 aba abab 800.0 900.0
1 aaa acc 900.0 60.0
2 bba jka Nan Nan
3 fff yy 809.0 400.0
4 hkm asa j Nan Nan
5 daa rr oo 521.0 490.0
6 jtuy ww ddw 290.0 321.0
8 bkam ftf 88.0 Nan
9 fgqefc Nan 600.0
10 daas we fg Nan Nan
11 judv mm mk Nan Nan
12 hus gg hhh Nan Nan
不知道df1怎么用shift和match实现,谁能解决?
这是一个可能不是最佳的建议:
步骤 1:apply
的准备工作:
match = df['column1'].str.fullmatch('|'.join(entry for entry in my_list))
df['shift'] = match.cumsum()
df['index'] = df.index
df.set_index('column1', drop=True, inplace=True)
结果 (df
) 看起来像:
column2 column3 shift index
column1
aba abab 800.0 900.0 0 0
aaa acc 900.0 60.0 0 1
bba jka 809.0 400.0 1 2
fff yy 521.0 490.0 1 3
hkm asa j 290.0 321.0 2 4
daa rr oo 88.0 NaN 2 5
...
第 2 步:通过 apply
和 NaN
通过掩码 match
:
分配的“移位”
df = df.apply(lambda row: df.shift(int(row.at['shift'])).iloc[int(row.at['index'])],
axis='columns')
df[list(match)] = np.nan
步骤 3:清理:
df.drop(['shift', 'index'], axis='columns', inplace=True)
df.reset_index(inplace=True)
结果如期而至:
column1 column2 column3
0 aba abab 800.0 900.0
1 aaa acc 900.0 60.0
2 bba jka NaN NaN
3 fff yy 809.0 400.0
4 hkm asa j NaN NaN
5 daa rr oo 521.0 490.0
6 jtuy ww ddw 290.0 321.0
7 bkam ftf 88.0 NaN
8 fgqefc NaN 600.0
9 daas we fg NaN NaN
10 judv mm mk NaN NaN
11 hus gg hhh NaN NaN
但我不喜欢在 apply
中使用 df.shift
。问题是 第一行 中的可能匹配会导致没有 shift
的错误结果。这是一个避免这个问题的版本,在 apply
:
中更直接
# Preparation
df = pd.concat(
[pd.DataFrame({col: ['NOT IN LIST' if i == 0 else np.nan]
for i, col in enumerate(df.columns)}), df],
axis='index',
ignore_index=True
)
match = df['column1'].str.fullmatch('|'.join(entry for entry in my_list))
df['shift'] = df.index - match.cumsum()
df.set_index('column1', drop=True, inplace=True)
# Shifting etc.
df = df.apply(lambda row: df.iloc[int(row.at['shift'])], axis='columns')
df[list(match)] = np.nan
# Clean up
df.drop('NOT IN LIST', axis='index', inplace=True)
df.drop('shift', axis='columns', inplace=True)
df.reset_index(inplace=True)
(这里假设字符串 'NOT IN LIST'
不在 my_list
中。很可能空字符串 ''
也是一个不错的选择。)
我想重新排列包含 Nan 的列名称值。
我想要的条件是,如果列表中的字符串与列 [1] 匹配,它只会重新移动包含匹配字符串下的行的列值,因此它是我移动前的数据框。
[in] : df
[Out]:
column1 column2 column3
0 aba abab 800.0 900.0
1 aaa acc 900.0 60.0
2 bba jka 809.0 400.0
3 fff yy 521.0 490.0
4 hkm asa j 290.0 321.0
5 daa rr oo 88.0 Nan
6 jtuy ww ddw Nan 600.0
8 bkam ftf Nan Nan
9 fgqefc Nan Nan
10 daas we fg Nan Nan
11 judv mm mk Nan Nan
12 hus gg hhh Nan Nan
这是我的列表
my_list= ['bba jka', 'hkm asa j']
所以这是我想要的数据框,名称是 df1
column1 column2 column3
0 aba abab 800.0 900.0
1 aaa acc 900.0 60.0
2 bba jka Nan Nan
3 fff yy 809.0 400.0
4 hkm asa j Nan Nan
5 daa rr oo 521.0 490.0
6 jtuy ww ddw 290.0 321.0
8 bkam ftf 88.0 Nan
9 fgqefc Nan 600.0
10 daas we fg Nan Nan
11 judv mm mk Nan Nan
12 hus gg hhh Nan Nan
不知道df1怎么用shift和match实现,谁能解决?
这是一个可能不是最佳的建议:
步骤 1:apply
的准备工作:
match = df['column1'].str.fullmatch('|'.join(entry for entry in my_list))
df['shift'] = match.cumsum()
df['index'] = df.index
df.set_index('column1', drop=True, inplace=True)
结果 (df
) 看起来像:
column2 column3 shift index
column1
aba abab 800.0 900.0 0 0
aaa acc 900.0 60.0 0 1
bba jka 809.0 400.0 1 2
fff yy 521.0 490.0 1 3
hkm asa j 290.0 321.0 2 4
daa rr oo 88.0 NaN 2 5
...
第 2 步:通过 apply
和 NaN
通过掩码 match
:
df = df.apply(lambda row: df.shift(int(row.at['shift'])).iloc[int(row.at['index'])],
axis='columns')
df[list(match)] = np.nan
步骤 3:清理:
df.drop(['shift', 'index'], axis='columns', inplace=True)
df.reset_index(inplace=True)
结果如期而至:
column1 column2 column3
0 aba abab 800.0 900.0
1 aaa acc 900.0 60.0
2 bba jka NaN NaN
3 fff yy 809.0 400.0
4 hkm asa j NaN NaN
5 daa rr oo 521.0 490.0
6 jtuy ww ddw 290.0 321.0
7 bkam ftf 88.0 NaN
8 fgqefc NaN 600.0
9 daas we fg NaN NaN
10 judv mm mk NaN NaN
11 hus gg hhh NaN NaN
但我不喜欢在 apply
中使用 df.shift
。问题是 第一行 中的可能匹配会导致没有 shift
的错误结果。这是一个避免这个问题的版本,在 apply
:
# Preparation
df = pd.concat(
[pd.DataFrame({col: ['NOT IN LIST' if i == 0 else np.nan]
for i, col in enumerate(df.columns)}), df],
axis='index',
ignore_index=True
)
match = df['column1'].str.fullmatch('|'.join(entry for entry in my_list))
df['shift'] = df.index - match.cumsum()
df.set_index('column1', drop=True, inplace=True)
# Shifting etc.
df = df.apply(lambda row: df.iloc[int(row.at['shift'])], axis='columns')
df[list(match)] = np.nan
# Clean up
df.drop('NOT IN LIST', axis='index', inplace=True)
df.drop('shift', axis='columns', inplace=True)
df.reset_index(inplace=True)
(这里假设字符串 'NOT IN LIST'
不在 my_list
中。很可能空字符串 ''
也是一个不错的选择。)