根据与行相关和与列相关的条件设置数据帧值

时间:2019-01-24 17:21:14

标签: python pandas dataframe

情况

考虑一个包含以下列的数据框df

  • 名为amount的一列。此列中的所有值都是整数> 0或NaN。
  • 名为property_1property_2property_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值。

我觉得必须有一些巧妙的方法来完成某些矢量化数据帧操作。有人知道到底有多精确吗?

1 个答案:

答案 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