我有一个像这样的结构的pandas DataFrame:
df = pd.DataFrame( [
[ 'foo1', 'a', 'z', 'bar1', 1, 4 ],
[ 'foo2', 'b', 'y', 'bar2', 2, 5 ],
[ 'foo3', 'c', 'x', 'bar3', 3, 6 ]
] )
df.columns = [ 'foo', 'let1', 'let2', 'bar', 'num1', 'num2' ]
print( df )
foo let1 let2 bar num1 num2
0 foo1 a z bar1 1 4
1 foo2 b y bar2 2 5
2 foo3 c x bar3 3 6
我想要堆叠列let1
和let2
,并添加一个标签,告诉它们来自哪里。 num1
和num2
也是如此。最后,我想实现这个目标:
foo let letval bar num numval
0 foo1 let1 a bar1 num1 1
1 foo2 let1 b bar2 num1 2
2 foo3 let1 c bar3 num1 3
3 foo1 let2 z bar1 num2 4
4 foo2 let2 y bar2 num2 5
5 foo3 let2 x bar3 num2 6
到目前为止,我已经这样做了:
let = pd.concat( [ df.let1, df.let2 ] )
num = pd.concat( [ df.num1, df.num2 ] )
df = df.drop( ['let1', 'let2', 'num1', 'num2' ], axis=1 )
df = pd.concat( [ df, df ] )
df[ 'letval' ] = let
df[ 'numval' ] = num
print( df )
foo bar letval numval
0 foo1 bar1 a 1
1 foo2 bar2 b 2
2 foo3 bar3 c 3
0 foo1 bar1 z 4
1 foo2 bar2 y 5
2 foo3 bar3 x 6
但是,我很确定有一种更简单的方法可以实现这一点,而无需复制到虚拟变量和此类变通方法。
有什么想法吗?
答案 0 :(得分:4)
以下是我尝试将@ayhan的解决方案与pd.melt()方法结合使用:
In [191]: (pd.melt(df.drop(['num1','num2'], 1), id_vars=['foo','bar'],
.....: var_name='let', value_name='letval')
.....: .assign(numval=pd.lreshape(df.filter(like='num'),
.....: {'numval': ['num1', 'num2']})))
Out[191]:
foo bar let letval numval
0 foo1 bar1 let1 a 1
1 foo2 bar2 let1 b 2
2 foo3 bar3 let1 c 3
3 foo1 bar1 let2 z 4
4 foo2 bar2 let2 y 5
5 foo3 bar3 let2 x 6
答案 1 :(得分:2)
与此同时,我也得到了答案。
let = [ 'let1', 'let2' ]
num = [ 'num1', 'num2' ]
n = df.shape[0]
df = pd.lreshape(df, { 'letval': let, 'numval': num } )
df[ 'let' ] = [ item for item in let for _ in range(n) ]
df[ 'num' ] = [ item for item in num for _ in range(n) ]
print( df )
bar foo letval numval let num
0 bar1 foo1 a 1 let1 num1
1 bar2 foo2 b 2 let1 num1
2 bar3 foo3 c 3 let1 num1
3 bar1 foo1 z 4 let2 num2
4 bar2 foo2 y 5 let2 num2
5 bar3 foo3 x 6 let2 num2
答案 2 :(得分:1)
试试这个:
dfm = pd.melt(df.drop(['num1','num2'], 1), id_vars=['foo','bar'], var_name=('let'), value_name=('letval'))
dfm[['num', 'numvals']] = pd.melt(df.drop(['let1','let2'], 1), id_vars=['foo','bar'], var_name=('num'), value_name=('numvals'))[['num', 'numvals']]
dfm:
foo bar let letval num numvals
0 foo1 bar1 let1 a num1 1
1 foo2 bar2 let1 b num1 2
2 foo3 bar3 let1 c num1 3
3 foo1 bar1 let2 z num2 4
4 foo2 bar2 let2 y num2 5
5 foo3 bar3 let2 x num2 6