我有以下数据框:
df
id price1 price2 price_col1 price_col2
0 1 100.0 NaN price1 price2
1 2 200.0 NaN price2 price1
此处,列price_col1
和price_col2
包含同一数据框中存在的列名。例如,在这种情况下,price1
和price2
。
我的用例是,我为每一行获取所有价格列,并根据价格值是否为空来分配价格值
因此所需的输出将是:
df
id price1 price2 price_col1 price_col2 price_val
0 1 100.0 NaN price1 price2 100.0
1 2 200.0 NaN price2 price1 200.0
在这里,我为第一行分配price_val = 100
(等于price1
),因为在这种情况下,优先级为price1
,price2
。对于第二行,我根据优先级price_val=200
price1
分配price2
(再次等于price1
)。
基本上,我需要在遇到非null值时立即停止。
这可以通过使用pandas apply来实现,但是当数据达到数百万时,性能会受到影响。
关于不使用熊猫如何做到这一点的任何建议适用吗?
使用熊猫的解决方案适用:
def calculate_price(row):
df = pd.DataFrame(row).transpose()
columns = [c for c in df.columns if c.startswith('price_col')]
row['price_col_list'] = ''
for col in columns:
if row[col] != '' and not pd.isna(row[col]):
row['price_col_list'] += row[col] + ','
price_columns = row['price_col_list'].split(',')
price_columns = list(filter(None, price_columns))
row['price_val'] = np.NaN
for price_column in price_columns:
if not pd.isna(row[price_column]):
row['price_val'] = row[price_column]
else:
continue
return row['price_val']
df['price_val'] = df.apply(calculate_price,axis=1)
答案 0 :(得分:0)
IIUC,这样做:
# this is to search for the first non-null
s = df[['price1','price2']].ffill(1).stack()
# looking for the correct order
u = (df.filter(like='col')
.stack()
.reset_index(name='col')
.drop('level_1', axis=1)
)
s.loc[[*zip(u['level_0'], u['col'])]].groupby(level=0).first()
输出:
id price1 price2 price_col1 price_col2 price_val
0 1 100.0 NaN price1 price2 100.0
1 2 200.0 NaN price2 price1 200.0
2 3 100.0 200.0 price2 price1 200.0