Python / Pandas - 2 мультииндексных DataFrames визуально одинаковы, но не равны? - PullRequest
0 голосов
/ 01 мая 2020

Я использую 2 способа подачи мультииндекса pandas DataFrame:

  • тот, который инициализирует его значениями,

  • тот, который заполняет строку по строке (мне не важна скорость, я должен делать это так, как я получаю каждую новую строку после разных вычислений, а не сразу)

Пожалуйста, оба DataFrames «выглядят» одинаково, но pandas говорит мне, что это не так. Что мне делать, чтобы они были одинаковыми?

 import attr
 import pandas as pd

 @attr.s(frozen=True)
 class CDE(object):
     name : str = attr.ib()
     def __str__(self):
         return self.name

 # Method 1: filling it row per row.
 rmidx = pd.MultiIndex(levels=[[],[]], codes=[[],[]], names=['CDE','period'])
 c_array = [['Column', 'Column'],['First', 'Last']]
 cmidx = pd.MultiIndex.from_arrays(c_array)
 summary1 = pd.DataFrame(index = rmidx, columns=cmidx)
 mcde1 = CDE(name='hi')
 mcde2 = CDE(name='ho')
 values = [[20,30],[40,50]]
 period = '5m'
 summary1.loc[(mcde1, period),('Column',)]=values[0]
 summary1.loc[(mcde2, period),('Column',)]=values[1]

 # Method 2: all at once.
 columns = summary1.columns
 rows = summary1.index.names
 index_label = [[mcde1,mcde2],[period,period]]
 summary2 = pd.DataFrame(values, index=index_label, columns=columns)
 summary2.index.names = rows

 In [2]:summary1
 Out[2]: 
            Column     
             First Last
 CDE period            
 hi  5m         20   30
 ho  5m         40   50

 In [3]:summary2
 Out[3]: 
            Column     
             First Last
 CDE period            
 hi  5m         20   30
 ho  5m         40   50

Но

 summary1.equals(summary2)
 False

Почему это так? Спасибо за любой совет по этому поводу.

1 Ответ

3 голосов
/ 01 мая 2020

Из do c This function requires that the elements have the same dtype as their respective elements in the other Series or DataFrame. Но если вы сделаете

summary1.dtypes, summary2.dtypes

Вы получите

(Column  First    object
         Last     object
 dtype: object,
 Column  First    int64
         Last     int64
 dtype: object)

Это потому, что при создании пустого фрейма данных

summary1 = pd.DataFrame(index = rmidx, columns=cmidx)

по умолчанию dtype равно object. Поэтому, когда вы добавляете новую строку, данные преобразуются / маскируются как заданный dtype. С другой стороны, если вы создадите фрейм данных с данными, pandas попытается угадать лучший dtype, в данном случае int64.

...