熊猫:使用优先级创建具有列值的列

时间:2019-12-13 13:58:25

标签: python pandas

我有以下数据框:

df
   id  price1  price2 price_col1 price_col2
0   1   100.0     NaN     price1     price2
1   2   200.0     NaN     price2     price1

此处,列price_col1price_col2包含同一数据框中存在的列名。例如,在这种情况下,price1price2

我的用例是,我为每一行获取所有价格列,并根据价格值是否为空来分配价格值

因此所需的输出将是:

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),因为在这种情况下,优先级为price1price2。对于第二行,我根据优先级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)

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