Изменение формы данных в Python - PullRequest
3 голосов
/ 30 октября 2019

У меня есть фрейм данных Python Pandas, который можно упростить следующим образом:

python
df= pd.DataFrame([['January','Monday',np.nan,np.nan,np.nan,1,20],['January','Monday',np.nan,np.nan,np.nan,2,25],['February','Monday',np.nan,np.nan,np.nan,1,15],\
      ['February','Monday',np.nan,np.nan,np.nan,2,20],['February','Monday',np.nan,np.nan,np.nan,3,25],['March','Tuesday',np.nan,np.nan,np.nan,1,50],\
      ['March','Wednesday',np.nan,np.nan,np.nan,1,75]],columns = ['Month','Day','Data1','Data2', 'Data3','Count','Initial_Data'])
     Month        Day  Data1  Data2  Data3  Count  Initial_Data
0   January     Monday    NaN    NaN    NaN      1            20
1   January     Monday    NaN    NaN    NaN      2            25
2  February     Monday    NaN    NaN    NaN      1            15
3  February     Monday    NaN    NaN    NaN      2            20
4  February     Monday    NaN    NaN    NaN      3            25
5     March    Tuesday    NaN    NaN    NaN      1            50
6     March  Wednesday    NaN    NaN    NaN      1            75

Цель / цель нового фрейма данных: я хочу, чтобы данные классифицировались по месяцам и дням. Я хотел бы заполнить столбец Data1, Data2 и Data3 цифрой из Initial_Data. Так, например, для месяца январь и день понедельника, данные1 = 20, данные2 = 25 и данные3 остаются как NaN, потому что месяц январь и день понедельника имеет наибольшее число = 2. Для месяца февраль и день понедельник я хотел бы иметь данные1 = 15, данные2= 20 и Data3 = 25, это потому, что месяц февраль и день понедельник имеют самый высокий счет = 3. Для месяца мартовский день вторник я хотел бы иметь данные 1 = 50, данные 2 и данные 3 = NaN, а для месяца мартовский день среда я хотел бы иметь данные 1 = 75 и DAta2 = данные 3 = NaN, поскольку они имеют наибольшее число = 1. datafame должен выглядеть следующим образом:

      Month        Day  Data1  Data2  Data3
0   January     Monday     20   25.0    NaN
1   January     Monday     20   25.0    NaN
2  February     Monday     15   20.0   25.0
3  February     Monday     15   20.0   25.0
4  February     Monday     15   20.0   25.0
5     March    Tuesday     50    NaN    NaN
6     March  Wednesday     75    NaN    NaN

Я пытался использовать оператор if, но он не работает, так как я не могу найти решение для заполнения всех трех столбцов (Data1, Data2 и Data3). Большое спасибо заранее.

Ответы [ 2 ]

1 голос
/ 30 октября 2019

Вы можете попробовать это:

df2 = df.set_index(['Month','Day','Count'])['Initial_Data'].unstack().add_prefix('Data').reset_index()
df.merge(df2, on=['Month','Day'], suffixes=('_x',''))[df.columns]

Вывод:

      Month        Day  Data1  Data2  Data3  Count  Initial_Data
0   January     Monday   20.0   25.0    NaN      1            20
1   January     Monday   20.0   25.0    NaN      2            25
2  February     Monday   15.0   20.0   25.0      1            15
3  February     Monday   15.0   20.0   25.0      2            20
4  February     Monday   15.0   20.0   25.0      3            25
5     March    Tuesday   50.0    NaN    NaN      1            50
6     March  Wednesday   75.0    NaN    NaN      1            75

Подробности:

Сначала используйте set_index и unstack самый внутренний индексперейти к «Count» в столбцах. Таким образом, изменение формы данных. Затем добавьте префикс «Данные» к заголовкам столбцов.

Далее нам нужно merge или объединить два кадра данных на основе столбцов Месяц и День.

0 голосов
/ 30 октября 2019

Вот мой ответ, но Скотт опередил меня с этим гораздо лучше.

import numpy as np
import pandas as pd

df = pd.DataFrame([
    ['January','Monday',np.nan,np.nan,np.nan,1,20],\
    ['January','Monday',np.nan,np.nan,np.nan,2,25],\
    ['February','Monday',np.nan,np.nan,np.nan,1,15],\
    ['February','Monday',np.nan,np.nan,np.nan,2,20],\
    ['February','Monday',np.nan,np.nan,np.nan,3,25],\
    ['March','Tuesday',np.nan,np.nan,np.nan,1,50],\
    ['March','Wednesday',np.nan,np.nan,np.nan,1,75]],
    columns = ['Month','Day','Data1','Data2', 'Data3','Count','Initial_Data'])

new = pd.DataFrame(columns = ['Month','Day','Data1','Data2', 'Data3'])

for ridx, row in df.iterrows():
    new.loc[ridx] = [row['Month'], row['Day'], np.nan, np.nan, np.nan]
    if row['Count'] == 1:
        new.loc[new.index[ridx], 'Data1'] = row['Initial_Data']
    if row['Count'] == 2:
        new.loc[new.index[ridx], 'Data2'] = row['Initial_Data']
        new.loc[new.index[ridx-1], 'Data2'] = row['Initial_Data']
        new.loc[new.index[ridx], 'Data1'] = new.loc[new.index[ridx-1], 'Data1']
    if row['Count'] == 3:
        new.loc[new.index[ridx], 'Data3'] = row['Initial_Data']
        new.loc[new.index[ridx-1], 'Data3'] = row['Initial_Data']
        new.loc[new.index[ridx-2], 'Data3'] = row['Initial_Data']
        new.loc[new.index[ridx], 'Data1'] = new.loc[new.index[ridx-1], 'Data1']
        new.loc[new.index[ridx], 'Data2'] = new.loc[new.index[ridx-1], 'Data2']

print(new)

      Month        Day Data1 Data2 Data3
0   January     Monday    20    25   NaN
1   January     Monday    20    25   NaN
2  February     Monday    15    20    25
3  February     Monday    15    20    25
4  February     Monday    15    20    25
5     March    Tuesday    50   NaN   NaN
6     March  Wednesday    75   NaN   NaN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...