Предположим пример фрейма данных 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)
3
Michal 27 Май 2017 в 23:21

2 ответа

Лучший ответ
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 сместит строку / столбец целом , но как только у нас будет только одно значение в каждой строке / столбце, это сработает.

5
MaxU 27 Май 2017 в 21:52
>>> 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 таким образом.

4
spies006 27 Май 2017 в 21:21