将某些奇怪格式化的df行更改为列

问题描述 投票:2回答:1

我有一个包含数千行的数据帧,此示例df提供了存在的不同类型的行:

df = pd.DataFrame({'col1': ['1', '2', '2', '3'],
                  'col2': ['10', '15', '20', '30'],
                    'col3': ['cat', 'dog', 'cat', 'cat'],
                   'col4': [0.2, 0.9, 'dog', 0.5],
                  'col5': [None, None, 0.3, 'dog'],
                  'col6': [None, None, None, 0.1]})

col1col2原样很好。对于行的其余部分,我希望catdogcatdog成为列标题。当列标题存在于行中时,其后面的任何值都应该是该列中的值。

每行的规则:

  • 如果一行只包含cat,则小数值在cat列中(dogcatdog列具有None)。
  • 如果一行只包含dog,则小数值在dog列中(catcatdog列具有None)。
  • 如果一行有catdog,但只有1个十进制数,那么十进制数应该在catdog以及catdog之下。
  • 如果一行有catdog,但是有两个十进制数,则十进制数位于数字前面的列下(None下面的catdog)。

例如,在第一行中,0.2直接位于cat之后,因此它将进入该列(与来自110col1/col2连续)。

在第三排,0.3,在“catdog”之后,所以0.3进入所有列:catdogcatdog

期望的输出:

dfoutput = pd.DataFrame({'col1': ['1', '2', '2', '3'],
                  'col2': ['10', '15', '20', '30'],
                   'cat': [0.2, None, 0.3, 0.5],
                    'dog': [None, 0.9, 0.3, 0.1],
                    'catdog': [None, None, 0.3, None]})
python pandas dataframe
1个回答
1
投票

使用np.selectnp.where

cond1 = (df['col3']=='cat') & (df['col4']!='dog')
cond2 = (df['col3']=='cat') & (df['col4']=='dog')
cond3 = df['col3']=='dog'
cond4 = df['col5']=='dog'
cond5 = df['col4']=='dog'

df['cat'] = np.select([cond1, cond2], [df['col4'], df['col5']], None)
df['dog'] = np.select([cond3,cond4,cond5], [df['col4'], df['col6'], df['col5']], None)
df['catdog'] = np.where(cond2, df['col5'], None)

df.drop(['col3','col4','col5','col6'], axis=1, inplace=True)
print(df)

输出:

 col1 col2   cat   dog   catdog                                                                                                   
0    1   10  0.2   None  None                                                                                                   
1    2   15  None  0.9   None                                                                                                   
2    2   20  0.3   0.3   0.3                                                                                                   
3    3   30  0.5   0.1   None 
© www.soinside.com 2019 - 2024. All rights reserved.