Развернуть столбец pandas на основе типа ячейки

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

У меня есть следующий фрейм данных:

   field          value
0 longitude      100
1 altitude       200
2 location       China
3 date           20180303
......
  

Я хочу преобразовать этот фрейм данных в следующий формат:

    field      string_value int_value datetime_value boolean_value float_value field_type
0  longitude  NA           NA        NA             NA            100         float
1  altitude   NA           NA        NA             NA            200         float
2  location   China        NA        NA             NA            NA          str
3  date       NA           NA        20180303       NA            NA          datetime
......
  

Как я мог бы эффективно это сделать? Я думаю, что могу сделать это с apply , но это кажется медленным, потому что он проходит через фрейм данных строка за строкой. Есть ли более быстрый способ сделать это?

Комментарии:

1. Что такое print (df['value'].head().apply(type)) ?

2. Что-то вроде: 0 <class 'float'> 1 <class 'float'> 2 <class 'str'> 3 <class 'datetime'> Name: value, dtype: object

Ответ №1:

Идея заключается в том, чтобы получить type значения, преобразовать в строку и map в более удобочитаемую форму, затем для новых столбцов использовать DataFrame.set_index with Series.unstack и DataFrame.join в original:

 d = {'field': ['longitude', 'altitude', 'location', 'date','check'], 
     'value': [100, 200.5, 'China', pd.Timestamp('20180303'), True]}

df = pd.DataFrame(d)
#print (df)

d = {"<class 'bool'>":"bool",
     "<class 'float'>":"float",
     "<class 'int'>":"int",
     "<class 'str'>":"string",
     "<class 'pandas._libs.tslibs.timestamps.Timestamp'>":"datetime"}
s = df['value'].apply(type).astype(str).map(d).fillna('not defined type')
df = df.join(df.set_index(s, append=True)['value'].unstack())
df['field_type'] = s
print (df)
       field                value  bool             datetime  float  int  
0  longitude                  100   NaN                  NaN    NaN  100   
1   altitude                200.5   NaN                  NaN  200.5  NaN   
2   location                China   NaN                  NaN    NaN  NaN   
3       date  2018-03-03 00:00:00   NaN  2018-03-03 00:00:00    NaN  NaN   
4      check                 True  True                  NaN    NaN  NaN   

  string field_type  
0    NaN        int  
1    NaN      float  
2  China     string  
3    NaN   datetime  
4    NaN       bool  
  

Ответ №2:

Я думаю, что наиболее эффективный способ справиться с этим — создать новый столбец, в котором хранится тип каждого элемента в [‘value’], а затем использовать pandas.pivot_table() с индексом = [‘field’], значениями = [‘value’] и столбцами, являющимися столбцом, используемым для хранения dtypes.

Комментарии:

1. Вы пробовали это? Я получил ошибку DataError, говорящую No numeric types to aggregate

2. Есть несколько строк, поэтому pivot_table трудно фактически агрегировать значения.

3. Верно, извините! Вместо этого используйте ответ Израэля.