Измените формат данных pandas, чтобы превратить категориальные столбцы в отдельные столбцы - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть данные, которые выглядят так:

df = pd.DataFrame(data=[list('ABCDE'), 
          ['Crude Oil', 'Natural Gas', 'Gasoline', 'Diesel', 'Bitumen'],
          ['Natural Gas', 'Salt water', 'Waste water', 'Motor oil', 'Sour Gas'],
          ['Oil', 'Gas', 'Refined', 'Refined', 'Oil'],
          ['Gas', 'Water', 'Water', 'Oil', 'Gas'],
          list(np.random.randint(10, 100, 5)),
          list(np.random.randint(10, 100, 5))]
          ).T
df.columns =['ID', 'Substance1', 'Substance2', 'Category1', 'Category2', 'Quantity1', 'Quantity2']

  ID   Substance1  Substance2 Category1 Category2 Quantity1 Quantity2
0  A    Crude Oil  Natural Gas      Oil       Gas        85        14
1  B  Natural Gas   Salt water      Gas     Water        95        78
2  C     Gasoline  Waste water  Refined     Water        33        25
3  D       Diesel    Motor oil  Refined       Oil        49        54
4  E      Bitumen     Sour Gas      Oil       Gas        92        86

Столбцы Category и Quantity относятся к соответствующим столбцам Substance.

Я хочу расширить столбцы Category как новый столбец для каждого уникального значения и иметь значение Quantity в качестве значения ячейки. Несуществующие категории будут NaN. Таким образом, полученный кадр будет выглядеть так:

  ID   Oil  Gas Water Refined
0  A    85   14   NaN     NaN
1  B   NaN   95    78     NaN
2  C   NaN  NaN    25      33
3  D    54  NaN   NaN      49  
4  E    92   86   NaN     NaN

Я попытался .melt(), затем .pivot_table(), но по некоторым причинам значения дублируются в столбцах новой категории.

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Вот мой полу-ручной подход:

>>> df
  ID   Substance1   Substance2 Category1 Category2 Quantity1 Quantity2
0  A    Crude Oil  Natural Gas       Oil       Gas        74        49
1  B  Natural Gas   Salt water       Gas     Water        75        91
2  C     Gasoline  Waste water   Refined     Water        24        38
3  D       Diesel    Motor oil   Refined       Oil        19        95
4  E      Bitumen     Sour Gas       Oil       Gas        50        35
>>> newdf=pd.DataFrame(columns=set(df[['Category1','Category2']].values.flatten()),index=df.index)
>>> for name in newdf:                                                           
        newdf[name]=pd.concat([df[df['Category1']==name]['Quantity1'],df[df['Category2']==name]['Quantity2']])
...
>>> newdf
   Gas  Oil Water Refined
0   49   74   NaN     NaN
1   75  NaN    91     NaN
2  NaN  NaN    38      24
3  NaN   95   NaN      19
4   35   50   NaN     NaN
0 голосов
/ 15 ноября 2018

Вам нужно использовать pd.melt, затем groupby:

np.random.seed(0)

df = pd.DataFrame(data=[list('ABCDE'), 
          ['Crude Oil', 'Natural Gas', 'Gasoline', 'Diesel', 'Bitumen'],
          ['Natural Gas', 'Salt water', 'Waste water', 'Motor oil', 'Sour Gas'],
          ['Oil', 'Gas', 'Refined', 'Refined', 'Oil'],
          ['Gas', 'Water', 'Water', 'Oil', 'Gas'],
          list(np.random.randint(10, 100, 5)),
          list(np.random.randint(10, 100, 5))]
          ).T
df.columns =['ID', 'Substance1', 'Substance2', 'Category1', 'Category2', 'Quantity1', 'Quantity2']

pd.wide_to_long(df,['Substance','Category','Quantity'], 'ID','Num','','.+')\
  .groupby(['ID','Category'])['Quantity'].sum()\
  .unstack().reset_index()

Выход:

Category ID   Gas   Oil  Refined  Water
0         A  19.0  54.0      NaN    NaN
1         B  57.0   NaN      NaN   93.0
2         C   NaN   NaN     74.0   31.0
3         D   NaN  46.0     77.0    NaN
4         E  97.0  77.0      NaN    NaN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...