3 回答
TA贡献1817条经验 获得超6个赞
对于一般解决方案,您可以尝试以下两个选项之一:
您可以尝试这样做,使用OrderedDict
来获取按字母顺序排列的字母非数字列名称,pd.DataFrame.filter
以过滤具有相似名称的列,然后使用以下值连接值pd.DataFrame.stack
:
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
获取列名的另一种方法是使用reand setlike this,然后按字母顺序对列进行排序:
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
TA贡献1805条经验 获得超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
TA贡献1995条经验 获得超2个赞
c 列只有一列,而其他字母有两列,这一事实让它变得有点棘手。我首先堆叠数据框并去掉列名中的数字。然后对于 a 和 b,我旋转了一个数据框并删除了所有 nans。对于 c,我将数据帧的长度乘以 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
添加回答
举报