在 pandas 中,如何重新排列数据框以同时组合多组列?
In pandas, how to re-arrange the dataframe to simultaneously combine groups of columns?
希望有人能帮我解决问题。
给定一个 pandas 数据框,如下图所示,
我想将它重新安排到一个新的数据框中,组合几组列(这些组的大小都相同),这样每组就变成一个列,如下面的所需结果图像所示。
提前感谢您的任何提示。
对于一般解决方案,您可以尝试以下两个选项之一:
你可以试试这个,使用 OrderedDict
to get the alpha-nonnumeric column names ordered alphabetically, pd.DataFrame.filter
to filter the columns with similar names, and then concat the values with :
import pandas as pd
from collections import OrderedDict
df = pd.DataFrame([[0,1,2,3,4],[5,6,7,8,9]], columns=['a1','a2','b1','b2','c'])
newdf=pd.DataFrame()
for col in list(OrderedDict.fromkeys( ''.join(df.columns)).keys()):
if col.isalpha():
newdf[col]=df.filter(like=col, axis=1).stack().reset_index(level=1,drop=True)
newdf=newdf.reset_index(drop=True)
输出:
df
a1 a2 b1 b2 c
0 0 1 2 3 4
1 5 6 7 8 9
newdf
a b c
0 0 2 4
1 1 3 4
2 5 7 9
3 6 8 9
获取列名的另一种方法是像这样使用 re
和 set
,然后按字母顺序对列进行排序:
newdf=pd.DataFrame()
import re
for col in set(re.findall('[^\W\d_]',''.join(df.columns))):
newdf[col]=df.filter(like=col, axis=1).stack().reset_index(level=1,drop=True)
newdf=newdf.reindex(sorted(newdf.columns), axis=1).reset_index(drop=True)
输出:
newdf
a b c
0 0 2 4
1 1 3 4
2 5 7 9
3 6 8 9
c 列只有一列,而其他字母有两列,这一事实使它变得有点棘手。我首先堆叠数据框并去掉列名中的数字。然后对于 a 和 b,我旋转了一个数据框并删除了所有 nans。对于c,我将dataframe的长度乘以2使其匹配a和b,然后将其与a和b合并。
输入:
import pandas as pd
df = pd.DataFrame({'a1': {0: 0, 1: 5},
'a2': {0: 1, 1: 6},
'b1': {0: 2, 1: 7},
'b2': {0: 3, 1: 8},
'c': {0: 4, 1: 9}})
df
代码:
df1=df.copy().stack().reset_index().replace('[0-9]+', '', regex=True)
dfab = df1[df1['level_1'].isin(['a','b'])].pivot(index=0, columns='level_1', values=0) \
.apply(lambda x: pd.Series(x.dropna().values)).astype(int)
dfc = pd.DataFrame(np.repeat(df['c'].values,2,axis=0)).rename({0:'c'}, axis=1)
df2=pd.merge(dfab, dfc, how='left', left_index=True, right_index=True)
df2
输出:
a b c
0 0 2 4
1 1 3 4
2 5 7 9
3 6 8 9
您可以使用 pd.wide_to_long
和 rename
'c' 列来执行此操作:
df_out = pd.wide_to_long(df.reset_index().rename(columns={'c':'c1'}),
['a','b','c'],'index','no')
df_out = df_out.reset_index(drop=True).ffill().astype(int)
df_out
输出:
a b c
0 0 2 4
1 1 3 4
2 5 7 9
3 6 8 9
相同的数据帧只是排序不同。
pd.wide_to_long(df, ['a','b'], 'c', 'no').reset_index().drop('no', axis=1)
输出:
c a b
0 4 0 2
1 9 5 7
2 4 1 3
3 9 6 8
希望有人能帮我解决问题。
给定一个 pandas 数据框,如下图所示,
我想将它重新安排到一个新的数据框中,组合几组列(这些组的大小都相同),这样每组就变成一个列,如下面的所需结果图像所示。
提前感谢您的任何提示。
对于一般解决方案,您可以尝试以下两个选项之一:
你可以试试这个,使用 OrderedDict
to get the alpha-nonnumeric column names ordered alphabetically, pd.DataFrame.filter
to filter the columns with similar names, and then concat the values with
import pandas as pd
from collections import OrderedDict
df = pd.DataFrame([[0,1,2,3,4],[5,6,7,8,9]], columns=['a1','a2','b1','b2','c'])
newdf=pd.DataFrame()
for col in list(OrderedDict.fromkeys( ''.join(df.columns)).keys()):
if col.isalpha():
newdf[col]=df.filter(like=col, axis=1).stack().reset_index(level=1,drop=True)
newdf=newdf.reset_index(drop=True)
输出:
df
a1 a2 b1 b2 c
0 0 1 2 3 4
1 5 6 7 8 9
newdf
a b c
0 0 2 4
1 1 3 4
2 5 7 9
3 6 8 9
获取列名的另一种方法是像这样使用 re
和 set
,然后按字母顺序对列进行排序:
newdf=pd.DataFrame()
import re
for col in set(re.findall('[^\W\d_]',''.join(df.columns))):
newdf[col]=df.filter(like=col, axis=1).stack().reset_index(level=1,drop=True)
newdf=newdf.reindex(sorted(newdf.columns), axis=1).reset_index(drop=True)
输出:
newdf
a b c
0 0 2 4
1 1 3 4
2 5 7 9
3 6 8 9
c 列只有一列,而其他字母有两列,这一事实使它变得有点棘手。我首先堆叠数据框并去掉列名中的数字。然后对于 a 和 b,我旋转了一个数据框并删除了所有 nans。对于c,我将dataframe的长度乘以2使其匹配a和b,然后将其与a和b合并。
输入:
import pandas as pd
df = pd.DataFrame({'a1': {0: 0, 1: 5},
'a2': {0: 1, 1: 6},
'b1': {0: 2, 1: 7},
'b2': {0: 3, 1: 8},
'c': {0: 4, 1: 9}})
df
代码:
df1=df.copy().stack().reset_index().replace('[0-9]+', '', regex=True)
dfab = df1[df1['level_1'].isin(['a','b'])].pivot(index=0, columns='level_1', values=0) \
.apply(lambda x: pd.Series(x.dropna().values)).astype(int)
dfc = pd.DataFrame(np.repeat(df['c'].values,2,axis=0)).rename({0:'c'}, axis=1)
df2=pd.merge(dfab, dfc, how='left', left_index=True, right_index=True)
df2
输出:
a b c
0 0 2 4
1 1 3 4
2 5 7 9
3 6 8 9
您可以使用 pd.wide_to_long
和 rename
'c' 列来执行此操作:
df_out = pd.wide_to_long(df.reset_index().rename(columns={'c':'c1'}),
['a','b','c'],'index','no')
df_out = df_out.reset_index(drop=True).ffill().astype(int)
df_out
输出:
a b c
0 0 2 4
1 1 3 4
2 5 7 9
3 6 8 9
相同的数据帧只是排序不同。
pd.wide_to_long(df, ['a','b'], 'c', 'no').reset_index().drop('no', axis=1)
输出:
c a b
0 4 0 2
1 9 5 7
2 4 1 3
3 9 6 8