Pandas: Ошибка: Pivot Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ для MultiIndex, Ссли ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ индСкс.

Π‘ΠΎΠ·Π΄Π°Π½Π½Ρ‹ΠΉ Π½Π° 27 нояб. 2018  Β·  5ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ  Β·  Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: pandas-dev/pandas

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ΄Π°, ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€

df  = pd.DataFrame([['A', 'A1', 'label1', 1],
             ['A', 'A2', 'label2', 2],
             ['B', 'A1', 'label1', 3],
             ['B', 'A2', 'label2', 4]], columns=['index_1', 'index_2', 'label', 'value'])
df = df.set_index(['index_1', 'index_2'])

pivoted_df = df.pivot(index=None,
                     columns='label',
                     values = 'value')

ОписаниС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹

Ѐункция Pivot Π²Ρ‹Π΄Π°Π΅Ρ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ NotImplementedError: isna is not defined for MultiIndex . Когда index установлСн Π² None .


---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
<ipython-input-84-54426dadf31d> in <module>()
      2 pivoted_df = df.pivot(index=None,
      3                      columns='label',
----> 4                      values = 'value')

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\frame.py in pivot(self, index, columns, values)
   5192         """
   5193         from pandas.core.reshape.reshape import pivot
-> 5194         return pivot(self, index=index, columns=columns, values=values)
   5195 
   5196     _shared_docs['pivot_table'] = """

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\reshape\reshape.py in pivot(self, index, columns, values)
    404         else:
    405             index = self[index]
--> 406         index = MultiIndex.from_arrays([index, self[columns]])
    407 
    408         if is_list_like(values) and not isinstance(values, tuple):

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\indexes\multi.py in from_arrays(cls, arrays, sortorder, names)
   1272         from pandas.core.arrays.categorical import _factorize_from_iterables
   1273 
-> 1274         labels, levels = _factorize_from_iterables(arrays)
   1275         if names is None:
   1276             names = [getattr(arr, "name", None) for arr in arrays]

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\arrays\categorical.py in _factorize_from_iterables(iterables)
   2541         # For consistency, it should return a list of 2 lists.
   2542         return [[], []]
-> 2543     return map(list, lzip(*[_factorize_from_iterable(it) for it in iterables]))

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\arrays\categorical.py in <listcomp>(.0)
   2541         # For consistency, it should return a list of 2 lists.
   2542         return [[], []]
-> 2543     return map(list, lzip(*[_factorize_from_iterable(it) for it in iterables]))

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\arrays\categorical.py in _factorize_from_iterable(values)
   2513         codes = values.codes
   2514     else:
-> 2515         cat = Categorical(values, ordered=True)
   2516         categories = cat.categories
   2517         codes = cat.codes

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\arrays\categorical.py in __init__(self, values, categories, ordered, dtype, fastpath)
    359 
    360             # we're inferring from values
--> 361             dtype = CategoricalDtype(categories, dtype.ordered)
    362 
    363         elif is_categorical_dtype(values):

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\dtypes\dtypes.py in __init__(self, categories, ordered)
    136 
    137     def __init__(self, categories=None, ordered=None):
--> 138         self._finalize(categories, ordered, fastpath=False)
    139 
    140     <strong i="12">@classmethod</strong>

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\dtypes\dtypes.py in _finalize(self, categories, ordered, fastpath)
    161         if categories is not None:
    162             categories = self.validate_categories(categories,
--> 163                                                   fastpath=fastpath)
    164 
    165         self._categories = categories

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\dtypes\dtypes.py in validate_categories(categories, fastpath)
    318         if not fastpath:
    319 
--> 320             if categories.hasnans:
    321                 raise ValueError('Categorial categories cannot be null')
    322 

pandas\_libs\properties.pyx in pandas._libs.properties.CachedProperty.__get__()

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\indexes\base.py in hasnans(self)
   2237         """ return if I have any nans; enables various perf speedups """
   2238         if self._can_hold_na:
-> 2239             return self._isnan.any()
   2240         else:
   2241             return False

pandas\_libs\properties.pyx in pandas._libs.properties.CachedProperty.__get__()

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\indexes\base.py in _isnan(self)
   2218         """ return if each value is nan"""
   2219         if self._can_hold_na:
-> 2220             return isna(self)
   2221         else:
   2222             # shouldn't reach to this condition by checking hasnans beforehand

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\dtypes\missing.py in isna(obj)
    104     Name: 1, dtype: bool
    105     """
--> 106     return _isna(obj)
    107 
    108 

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\dtypes\missing.py in _isna_new(obj)
    115     # hack (for now) because MI registers as ndarray
    116     elif isinstance(obj, ABCMultiIndex):
--> 117         raise NotImplementedError("isna is not defined for MultiIndex")
    118     elif isinstance(obj, (ABCSeries, np.ndarray, ABCIndexClass,
    119                           ABCExtensionArray)):

NotImplementedError: isna is not defined for MultiIndex

ΠžΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚

index_1 | index_2 | label1 | label2
- | - | - | -
A | A1 | 1.0 | NaN
|| A2 | NaN | 2.0
B | A1 | 3,0 | NaN
|| A2 | NaN | 4.0

Π’Ρ‹Π²ΠΎΠ΄ pd.show_versions()

Π£Π‘Π’ΠΠΠžΠ’Π›Π•ΠΠΠ«Π• Π’Π•Π Π‘Π˜Π˜

ΠΊΠΎΠΌΠΌΠΈΡ‚: НСт
ΠΏΠΈΡ‚ΠΎΠ½: 3.6.5.final.0
Π±ΠΈΡ‚Ρ‹ Python: 64
ОБ: Windows
ОБ-Ρ€Π΅Π»ΠΈΠ·: 10
машина: AMD64
процСссор: Intel64 Family 6 Model 85 Stepping 4, GenuineIntel
byteorder: малСнький
LC_ALL: НСт
Π―Π—Π«Πš: НСт
ΠœΠ•Π‘Π’Πž: НСт.

ΠΏΠ°Π½Π΄Ρ‹: 0.23.4
pytest: 3.5.1
ΠΏΡƒΠ½ΠΊΡ‚: 10.0.1
инструмСнты настройки: 39.1.0
Cython: 0,28,2
число: 1.15.4
scipy: 1.1.0
pyarrow: НСт
xarray: НСт
IPython: 6.4.0
сфинкс: 1.7.4
ΠŸΡΡ‚ΡΠΈ: 0.5.0
dateutil: 2.7.3
pytz: 2018.4
blosc: НСт
ΡƒΠ·ΠΊΠΎΠ΅ мСсто: 1.2.1
Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹: 3.4.3
numexpr: 2.6.5
ΠΏΠ΅Ρ€ΠΎ: НСт
matplotlib: 2.2.2
openpyxl: 2.5.3
xlrd: 1.1.0
xlwt: 1.3.0
xlsxwriter: 1.0.4
Π»Ρ…ΠΌΠ»: 4.2.1
BS4: 4.6.0
html5lib: 1.0.1
sqlalchemy: 1.2.7
pymysql: НСт
psycopg2: НСт
jinja2: 2.10
s3fs: НСт
fastparquet: НСт
pandas_gbq: НСт
pandas_datareader: НСт

Π‘Π°ΠΌΡ‹ΠΉ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΉ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ

Бпасибо Π·Π° Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ https://github.com/pandas-dev/pandas/issues/23955#issuecomment -480804068. Если это ΠΊΠΎΠΌΡƒ-Ρ‚ΠΎ избавляСт ΠΎΡ‚ нСприятностСй, Π²ΠΎΡ‚ ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅

def multiindex_pivot(df, columns=None, values=None):
    #https://github.com/pandas-dev/pandas/issues/23955
    names = list(df.index.names)
    df = df.reset_index()
    list_index = df[names].values
    tuples_index = [tuple(i) for i in list_index] # hashable
    df = df.assign(tuples_index=tuples_index)
    df = df.pivot(index="tuples_index", columns=columns, values=values)
    tuples_index = df.index  # reduced
    index = pd.MultiIndex.from_tuples(tuples_index, names=names)
    df.index = index
    return df

ВсС 5 ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ

Π•ΡΡ‚ΡŒ обновлСния ΠΏΠΎ этому ΠΏΠΎΠ²ΠΎΠ΄Ρƒ? Насколько я понимаю, Π² настоящСС врСмя ΠΌΠ΅Ρ‚ΠΎΠ΄ pivot() просто Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с нСсколькими индСксаторами, Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ index Π½Π΅ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ список, ΠΈ ΠΊΠΎΠ³Π΄Π° None Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ½ пытаСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ MultiIndex.

На Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ я Ρ€Π΅ΡˆΠ°ΡŽ эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ хакСрским способом, гСнСрируя ΠΎΠ΄ΠΈΠ½ индСкс ΠΊΠ°ΠΊ объСдинСниС Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΡƒΡ€ΠΎΠ²Π½Π΅ΠΉ исходных индСксов, сводя ΠΈΡ… ΠΈ Π·Π°Ρ‚Π΅ΠΌ рСконструируя Ρ€Π°Π·Π½Ρ‹Π΅ ΡƒΡ€ΠΎΠ²Π½ΠΈ MultiIndex, раздСляя ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½Π΅Π½Π½Ρ‹ΠΉ Π΅Π΄ΠΈΠ½Ρ‹ΠΉ индСкс. БлСдуя ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ @srajanpaliwal :

(df.reset_index()
 .assign(new_index=lambda dd: dd['index_1'].str.cat(dd['index_2'], sep='_'))
 .pivot(index='new_index', columns='label', values='value')
 .assign(index_1=lambda dd: dd.index.str.split('_').str.get(0),
         index_2=lambda dd: dd.index.str.split('_').str.get(1))
 .set_index(['index_1', 'index_2']))

Π’Ρ‹Π²ΠΎΠ΄:

| | этикСтка | label1 | label2 |
| --------- | --------- | -------- | -------- |
| index_1 | index_1 | | |
| А | A1 | 1.0 | NaN |
| | A2 | NaN | 2.0 | |
| B | A1 | 3.0 | NaN |
|| A2 | NaN | 4.0 | |

Π’ любом случаС, Π΅ΡΡ‚ΡŒ Π»ΠΈ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ MultiIndex Π½Π΅ принимаСтся с ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠ΅ΠΉ pivot() ?

Бпасибо Π·Π° Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ https://github.com/pandas-dev/pandas/issues/23955#issuecomment -480804068. Если это ΠΊΠΎΠΌΡƒ-Ρ‚ΠΎ избавляСт ΠΎΡ‚ нСприятностСй, Π²ΠΎΡ‚ ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅

def multiindex_pivot(df, columns=None, values=None):
    #https://github.com/pandas-dev/pandas/issues/23955
    names = list(df.index.names)
    df = df.reset_index()
    list_index = df[names].values
    tuples_index = [tuple(i) for i in list_index] # hashable
    df = df.assign(tuples_index=tuples_index)
    df = df.pivot(index="tuples_index", columns=columns, values=values)
    tuples_index = df.index  # reduced
    index = pd.MultiIndex.from_tuples(tuples_index, names=names)
    df.index = index
    return df

нСбольшая ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²ΠΊΠ° коммСнтария @gmacario для Сдинообразия с api pivot

def multiindex_pivot(df, index=None, columns=None, values=None):
    #https://github.com/pandas-dev/pandas/issues/23955
    if index is None:
        names = list(df.index.names)
        df = df.reset_index()
    else:
        names = index
    list_index = df[names].values
    tuples_index = [tuple(i) for i in list_index] # hashable
    df = df.assign(tuples_index=tuples_index)
    df = df.pivot(index="tuples_index", columns=columns, values=values)
    tuples_index = df.index  # reduced
    index = pd.MultiIndex.from_tuples(tuples_index, names=names)
    df.index = index
    return df

ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅:

df.pipe(multiindex_pivot, index=['idx_column1', 'idx_column2'], columns='foo', values='bar')

Π΅Ρ‰Π΅ ΠΎΠ΄Π½ΠΎ нСбольшоС ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Ρ‚Π°ΠΊΠΆΠ΅ позволяСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ нСсколько columns= (Π½Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€Π΅Π½ΠΎ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ, Π½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² ΠΌΠΎΠΈΡ… ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ…):

def multiindex_pivot(df, index=None, columns=None, values=None):
    # https://github.com/pandas-dev/pandas/issues/23955
    if index is None:
        names = list(df.index.names)
        df = df.reset_index()
    else:
        names = index
    df = df.assign(tuples_index=[tuple(i) for i in df[names].values])  # hashable
    df = df.assign(tuples_columns=[tuple(i) for i in df[columns].values])  # hashable
    df = df.pivot(index='tuples_index', columns='tuples_columns', values=values)
    df.index = pd.MultiIndex.from_tuples(df.index, names=names)  # reduced
    df.columns = pd.MultiIndex.from_tuples(df.columns, names=columns)  # reduced
    return df

ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅:

df.pipe(multiindex_pivot,
        index=['idx_column1', 'idx_column2'],
        columns=['col_column1', 'col_column2'],
        values='bar')

Π•Ρ‰Π΅ ΠΎΠ΄Π½Π° Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½Π½Π°Ρ вСрсия:

def multiIndex_pivot(df, index = None, columns = None, values = None):
    # https://github.com/pandas-dev/pandas/issues/23955
    output_df = df.copy(deep = True)
    if index is None:
        names = list(output_df.index.names)
        output_df = output_df.reset_index()
    else:
        names = index
    output_df = output_df.assign(tuples_index = [tuple(i) for i in output_df[names].values])
    if isinstance(columns, list):
        output_df = output_df.assign(tuples_columns = [tuple(i) for i in output_df[columns].values])  # hashable
        output_df = output_df.pivot(index = 'tuples_index', columns = 'tuples_columns', values = values) 
        output_df.columns = pd.MultiIndex.from_tuples(output_df.columns, names = columns)  # reduced
    else:
        output_df = output_df.pivot(index = 'tuples_index', columns = columns, values = values)    
    output_df.index = pd.MultiIndex.from_tuples(output_df.index, names = names)
    return output_df

ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅:

df.pipe(multiIndex_pivot, index = ['idx_column1', 'idx_column2'], columns = ['col_column1', 'col_column2'], values = 'bar')
Π‘Ρ‹Π»Π° Π»ΠΈ эта страница ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ?
0 / 5 - 0 Ρ€Π΅ΠΉΡ‚ΠΈΠ½Π³ΠΈ