有没有可能使用Pandas来重塑这个?

31moq8wy  于 2023-08-01  发布在  其他
关注(0)|答案(3)|浏览(87)

我有这个数据框(包含所有50个状态和更多类别,但如果我们能让它工作,我可以将其应用于整个数据集):

US     US_bp   US_bp%       AL   AL_bp  AL_bp%
total_pop   324173084  41393176     12.8  4920613  794326    16.1
white       198511109  19510415      9.8  3218517  378269    11.8
black        38526055   8402643     21.8  1260356  327284    26.0

字符串
需要这个:

place  total_pop        bp    bp%  white_pop  white_bp  white_bp%  black_pop  black_bp  black_bp%
0      US  324173084  41393176   12.8  198511109  19510415        9.8    8402643    840263       21.4
1      AL    4920613    794326   16.1    3218517    378269       11.8    1260356    327284       26.0


我怎么能和Pandas一起做这件事?我试过融化和旋转,但不能包我的头周围什么可能工作。

gkl3eglg

gkl3eglg1#

以下是部分解决方案:将列转换为MultiIndex,然后进行堆叠和取消堆叠。
我使用正则表达式作为第一步:提取两个大写字符,可选地后跟一个下划线和另一部分。

col_pairs = df.columns.str.extract(r'^([A-Z]{2})(?:_(.*))?$').fillna('pop')
df.columns = pd.MultiIndex.from_arrays(col_pairs.T.values)

(df
    .stack(level=0)
    .unstack(level=0)
    .swaplevel(axis=1)
    # Fix order
    .reindex(df.index, axis=1, level=0)
    .reindex(df.columns.get_level_values(1).unique(), axis=1, level=1)
    .reindex(df.columns.get_level_values(0).unique())
    )

个字符
我更希望堆栈/解堆栈不排序,但至少you can fix that by reindexing。我也不想麻烦得到你想要的标签,但大部分都很容易。

fwzugrvs

fwzugrvs2#

另一个解决方案,使用pd.wide_to_long

stubnames = sorted(set(c.split('_')[0] for c in df.columns))
df.columns = (c if '_' in c else c + '_total_pop' for c in df.columns)
df = df.rename(index={'total_pop': ''})

df = pd.wide_to_long(df.reset_index(), stubnames, i='index', j='xxx', sep='_', suffix=r'.*').T
df.columns = (f'{a}_{b}'.strip('_') for a, b in df.columns)

print(df)

字符串
图纸:

total_pop  white_total_pop  black_total_pop          bp    white_bp   black_bp   bp%  white_bp%  black_bp%
AL    4920613.0        3218517.0        1260356.0    794326.0    378269.0   327284.0  16.1       11.8       26.0
US  324173084.0      198511109.0       38526055.0  41393176.0  19510415.0  8402643.0  12.8        9.8       21.8

rsl1atfo

rsl1atfo3#

  • 重命名列以迎合那些没有以_结尾的列:
df.columns = [f"{col}_pop" if "bp" not in col else col for col in df]

字符串

  • 从列创建MultiIndex:
df.columns = df.columns.str.split("_", expand=True)

  • 使用stack、unstack、swaplevel的组合重塑数据框架:
df = df.stack(level=0).unstack(level=0).swaplevel(axis=1)

  • 运行一个列表解析来构建最后一列,以达到预期的输出:
df.columns = [first if last in first 
              else last if first == "total_pop" 
              else f"{first}_{last}" 
              for first, last in df]

df.index.name = 'place'

       black_bp        bp  white_bp  black_bp%   bp%  white_bp%  black_pop  total_pop  white_pop
place                                                                                           
AL       327284    794326    378269       26.0  16.1       11.8    1260356    4920613    3218517
US      8402643  41393176  19510415       21.8  12.8        9.8   38526055  324173084  198511109

相关问题