如果列中的值不是NaN(Pandas),则迭代遍历对象框架并创建新的列

afdcj2ne  于 2023-11-15  发布在  其他
关注(0)|答案(3)|浏览(121)
df = pd.DataFrame({
    'subsegment': ['corp', np.nan, 'terr'],
    'region': ['japan', np.nan, np.nan],
    'subregion': [np.nan, 'se', 'ne'], 
    'segment': [np.nan,'ent','comm']
})

字符串
我试图通过以上的框架,如果值不是NaN比添加列标题作为值或值的一部分(取决于有多少NaN)在新列“模式”。
原始DF
| 子段|区域|次区域|段|
| --|--|--|--|
| Corp|日本|楠|楠|
| 楠|楠|se| ent|
| Terr|楠|ne| Comm|
期望输出DF
| 子段|区域|次区域|段|模式|
| --|--|--|--|--|
| Corp|日本|楠|楠|子段区域|
| 楠|楠|se| ent|子区域段|
| Terr|楠|ne| Comm|亚段-亚段-段|
我曾尝试创建单独的较小的dfs,其中包含所有不为null的列的组合,然后将这些dfs连接在一起,但这似乎效率极低。

df1 = df.loc[~(df['subsegment'].isna()) & (~df['region'].isna()) & (~df['region'].isna())]
df2 = df.loc[~(df['region'].isna()) & (~df['subregion'].isna()) & (~df['segment'].isna())]
df3 = df.loc[~(df['subsegment'].isna()) & (~df['subregion'].isna()) & (~df['segment'].isna())] 

pd.concat(df1,df2,df3.....)

dced5bon

dced5bon1#

您可以使用dot产品:

df['mode'] = (df.notna() @ (df.columns+'-')).str[:-1]

字符串
输出量:

subsegment region subregion segment                          mode
0       corp  japan       NaN     NaN             subsegment-region
1        NaN    NaN        se     ent             subregion-segment
2       terr    NaN        ne    comm  subsegment-subregion-segment


或者,使用经典的groupby.agg

s = df.notna().stack()

df['mode'] = s[s].reset_index().groupby('level_0')['level_1'].agg('-'.join)


或自定义聚合:

df['mode'] = df.notna().mul(df.columns).agg(lambda x: '-'.join(x[x.ne('')]), axis=1)

n3ipq98p

n3ipq98p2#

您可以使用下面的代码。我使用apply和一个自定义函数,该函数只查找非空的列

from itertools import compress
def temp_func(x, cols):

    list_a = (~x.isna()).to_list()
    ret = list(compress(cols, list_a))
    return '-'.join(ret)
df['mode']= df.apply(lambda x: temp_func(x, list(df.columns)), axis=1)
print(df)

字符串
输出:

subsegment region subregion segment                          mode
0       corp  japan       NaN     NaN             subsegment-region
1        NaN    NaN        se     ent             subregion-segment
2       terr    NaN        ne    comm  subsegment-subregion-segment

cld4siwp

cld4siwp3#

一个可能的解决方案:

a = df.columns.values * (~pd.isnull(df.values))

df['mode'] = ['-'.join(a[i,:][a[i,:] != '']) for i in range(a.shape[0])]

字符串
或者:

df['mode'] = df.apply(lambda x: '-'.join(df.columns[~x.isna()]), axis=1)


输出量:

subsegment region subregion segment                          mode
0       corp  japan       NaN     NaN             subsegment-region
1        NaN    NaN        se     ent             subregion-segment
2       terr    NaN        ne    comm  subsegment-subregion-segment

相关问题