Pandas从当前列集合中提取一组新列,并按分类列进行切片

lh80um4z  于 2023-04-10  发布在  其他
关注(0)|答案(2)|浏览(70)

我有表格
| 仓|A_颜色|B_颜色|A_尺寸|B_Size。|
| --------------|--------------|--------------|--------------|--------------|
| A|“红色”||五十||
| B||“蓝色”||六十|
我希望有一个共同的颜色和大小列,而不是像这样的每个类别的一组列
| 仓|颜色|尺寸|
| --------------|--------------|--------------|
| A|“红色”|五十|
| B|“蓝色”|六十|
我尝试了下面的方法,但是得到了['Color','Size']列的NaN值

bins = ['A', 'B', 'C', 'D', 'E']
    for b in bins:
        df.loc[df['Bins'] == b, ['Color', 'Size']] = \
            df.loc[df['Bins'] == b, [f'{b}_Color', f'{b}_Size']]

这只是一个示例,真实的数据包含大约10万行和300多列。

nbysray5

nbysray51#

你可以使用pd.wide_to_long。你只需要重命名你的列来匹配格式(A_Color -〉Color_A)

>>> (pd.wide_to_long(df.rename(columns=lambda x: '_'.join(x.split('_')[::-1])), 
                     stubnames=['Color', 'Size'], i='Category', j='Cat', 
                     sep='_', suffix='\w+')
       .query('Category == Cat').droplevel('Cat').reset_index())

  Category Color  Size
0        A   Red  50.0
1        B  Blue  60.0

详细信息:

# Rename columns
>>> df1 = df.rename(columns=lambda x: '_'.join(x.split('_')[::-1]))
  Category Color_A Color_B  Size_A  Size_B  # <- HERE
0        A     Red     NaN    50.0     NaN
1        B     NaN    Blue     NaN    60.0

# Reshape dataframe
>>> out = pd.wide_to_long(df1, stubnames=['Color', 'Size'], i='Category', j='Cat', sep='_', suffix='\w+')
             Color  Size
Category Cat            
A        A     Red  50.0  # Keep
B        A     NaN   NaN  # Drop
A        B     NaN   NaN  # Drop
B        B    Blue  60.0  # Keep

# Filter rows
>>> out = out.query('Category == Cat')
             Color  Size
Category Cat            
A        A     Red  50.0
B        B    Blue  60.0

# Get final dataframe
>>> out = out.droplevel('Cat').reset_index()
  Category Color  Size
0        A   Red  50.0
1        B  Blue  60.0
gopyfrb3

gopyfrb32#

一个想法是通过使用_拆分列来获得第一个非缺失值:

df1 = (df.set_index('Category')
         .groupby(lambda x: x.split('_')[-1], axis=1)
         .first()
         .reset_index())
print (df1)
  Category Color  Size
0        A   Red  50.0
1        B  Blue  60.0

使用lookup的解决方案:

categories = ['Size','Color']

for c in categories:
    idx, cols = pd.factorize(df['Category'].add(f'_{c}'))
    df[c] = df.reindex(cols, axis=1).to_numpy()[np.arange(len(df)), idx]

您的解决方案应该通过转换为numpy数组来更改:

for b in bins:
    df.loc[df['Category'] == b, ['Color', 'Size']] = \
        df.loc[df['Category'] == b, [f'{b}_Color', f'{b}_Size']].to_numpy()

相关问题