考虑一个包含以下列的数据框df
:
amount
的一列。此列中的所有值都是整数> 0或NaN。property_1
,property_2
,property_3
等的多个列。这些列中的值是任意的。一个简单的示例df
将是:
import numpy as np
import pandas as pd
data = [
[2, 7., 2., 4., 3.],
[np.nan, 8., 3., 4., 2.],
[3, 9., 1., 5., 6.],
[1, 8., 2., 4., 1.],
]
columns = ['amount', 'property_1', 'property_2', 'property_3', 'property_4']
df = pd.DataFrame(data, columns=columns)
在控制台输出中如下所示:
amount property_1 property_2 property_3 property_4
0 2.0 7.0 2.0 4.0 3.0
1 NaN 8.0 3.0 4.0 2.0
2 3.0 9.0 1.0 5.0 6.0
3 1.0 8.0 2.0 4.0 1.0
我想将df
转换成如下所示的数据框:
amount property_1 property_2 property_3 property_4
0 2.0 7.0 2.0 NaN NaN
1 NaN NaN NaN NaN NaN
2 3.0 9.0 1.0 5.0 NaN
3 1.0 8.0 NaN NaN NaN
基本上,我想在列名称的数字后缀大于amount
的值或amount
的值为NaN的所有位置设置NaN值。
我觉得必须有一些巧妙的方法来完成某些矢量化数据帧操作。有人知道到底有多精确吗?
答案 0 :(得分:2)
您可以使用np.subtract.outer
为第一个条件构造布尔掩码。由于所有正整数均大于0,因此第二个空条件通过fillna(0)
处理。
# extract integers from columns
ints = df.columns[1:].str.rsplit('_', n=1).str[-1].astype(int)
# perform elementwise comparison after replacing null amounts with 0
bool_arr = np.subtract.outer(ints, df['amount'].fillna(0)).T
# apply Boolean mask to selected columns
df.iloc[:, 1:] = df.iloc[:, 1:].mask(bool_arr > 0)
print(df)
amount property_1 property_2 property_3 property_4
0 2.0 7.0 2.0 NaN NaN
1 NaN NaN NaN NaN NaN
2 3.0 9.0 1.0 5.0 NaN
3 1.0 8.0 NaN NaN NaN