2017-05-27 270 views
3

移位值假设DF的数据帧的一个例子:移动/在大熊猫数据帧

A 
0 4.3 
1 75 
2 8.5 
3 4.0 
4 98 

我需要每个值从A列移动到每一列 - 每列一个值:

  • 从第二值开始:移动到第二列B
  • 第三值到第三塔C
  • 等等...

所需的输出:

A  B C D E 
0 4.3 NaN NaN NaN NaN 
1 NaN 75 NaN NaN NaN 
2 NaN NaN 8.5 NaN NaN 
3 NaN NaN NaN 4.0 NaN 
4 NaN NaN NaN Nan 98 

一个想法是给每个值复制到第二个栏,然后在以前的专栏或从一列shift值删除它另一个,但我不知道怎样应用这个...

MWE

import pandas as pd 
import numpy as np 

df=pd.DataFrame(data=np.random.randint(0,100,(5,5)), columns=['A','B','C','D','E']) 
df.iloc[:,1:] =np.nan 

df.iloc[[1],[1]] = df.iloc[[1],[0]] 
df.iloc[[1],[1]] = df.iloc[[1],[0]].shift(1,axis=1) 

回答

5
In [76]: import string 

In [77]: r = pd.DataFrame(np.eye(len(df)), 
          columns=list(string.ascii_uppercase[:len(df)])) \ 
       .replace(0, np.nan) * df.A.values 

In [78]: r 
Out[78]: 
    A  B C D  E 
0 4.3 NaN NaN NaN NaN 
1 NaN 75.0 NaN NaN NaN 
2 NaN NaN 8.5 NaN NaN 
3 NaN NaN NaN 4.0 NaN 
4 NaN NaN NaN NaN 98.0 

或更好:

In [11]: r = pd.DataFrame(index=df.index, columns=list(string.ascii_uppercase[:len(df)])) 

In [12]: np.fill_diagonal(r.values, df.A) 

In [13]: r 
Out[13]: 
    A B C D E 
0 4.3 NaN NaN NaN NaN 
1 NaN 75 NaN NaN NaN 
2 NaN NaN 8.5 NaN NaN 
3 NaN NaN NaN 4 NaN 
4 NaN NaN NaN NaN 98 

UPDATE:

如何 “动” 单值

我们可以使用Series.shift方法。

水平移动:

In [94]: r.loc[1] = r.loc[1].shift(3) 

In [95]: r 
Out[95]: 
    A B C D  E 
0 4.3 NaN NaN NaN NaN 
1 NaN NaN NaN NaN 75.0 
2 NaN NaN 8.5 NaN NaN 
3 NaN NaN NaN 4.0 NaN 
4 NaN NaN NaN NaN 98.0 

垂直运动:

In [96]: r.loc[:, 'D'] = r.loc[:, 'D'].shift(-2) 

In [97]: r 
Out[97]: 
    A B C D  E 
0 4.3 NaN NaN NaN NaN 
1 NaN NaN NaN 4.0 75.0 
2 NaN NaN 8.5 NaN NaN 
3 NaN NaN NaN NaN NaN 
4 NaN NaN NaN NaN 98.0 

注:shift整个行/列移,但只要我们在每个只有一个值行/列这将工作。

+0

谢谢你的回答!你知道如何将列A中的值“移动”到任何列和任何行 - 不是对角吗? – Michal

+0

@Michal,你可以制作一个可重复的例子吗? – MaxU

+0

例如,要将值75移动到D列或8.5列到E列,或者甚至将8.5移动到第二行,E列。 – Michal

3
>>> import pandas as pd 
>>> import numpy as np 
>>> df = pd.DataFrame({'A':[4.3, 75, 8.5, 4.0, 98]}) 
>>> df 
     A 
0 4.3 
1 75.0 
2 8.5 
3 4.0 
4 98.0 


>>> diag_df = pd.DataFrame(np.diag(df.A), index=df.index, columns=['A', 'B', 'C', 'D', 'E']) 
>>> diag_df.replace(0, np.nan, inplace=True) 
>>> diag_df 
    A  B C D  E 
0 4.3 NaN NaN NaN NaN 
1 NaN 75.0 NaN NaN NaN 
2 NaN NaN 8.5 NaN NaN 
3 NaN NaN NaN 4.0 NaN 
4 NaN NaN NaN NaN 98.0 

请记住,如果你有0沿对角线然后将它与NaN如果使用replace方法取代了这种方式。

+2

如果他们将在原来的'df'中会发生'0'值? ;) – MaxU

+1

@MaxU谢谢。我对此的解决方案太接近您的变更答案。我会做笔记。 – spies006