Как заменить пробелы подчеркиванием в мультииндексированном pandas кадре данных (pandas 1.0) - PullRequest
0 голосов
/ 03 апреля 2020

Я хочу заменить пробелы символами подчеркивания в именах столбцов мультииндексированного pandas фрейма данных, но метод, который я использую с обычным pandas фреймом данных, не работает, и я ищу решение.

Для воспроизводимого примера я приведу некоторые данные:

df_pivot.to_json()
'{"(\'Open Interest\', \'cu2003\')":{"1582016340553":0.0,"1582016340553":0.0},"(\'Open Interest\', \'cu2004\')":{"1582016340553":0.0,"1582016340553":0.0},"(\'Open Interest\', \'cu2005\')":{"1582016340553":0.0,"1582016340553":0.0},"(\'Open Interest\', \'cu2006\')":{"1582016340553":0.0,"1582016340553":0.0},"(\'Open Interest\', \'cu2007\')":{"1582016340553":0.0,"1582016340553":0.0}}'

Моя первоначальная попытка была:

df_pivot.columns = df_pivot.columns.str.replace(' ', '_')

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-153-c1c5f88f6ecd> in <module>
----> 1 df_pivot.columns = df_pivot.columns.str.replace(' ', '_')

~\Anaconda3\envs\tf2\lib\site-packages\pandas\core\accessor.py in __get__(self, obj, cls)
    185             # we're accessing the attribute of the class, i.e., Dataset.geo
    186             return self._accessor
--> 187         accessor_obj = self._accessor(obj)
    188         # Replace the property with the accessor object. Inspired by:
    189         # http://www.pydanny.com/cached-property.html

~\Anaconda3\envs\tf2\lib\site-packages\pandas\core\strings.py in __init__(self, data)
   2032 
   2033     def __init__(self, data):
-> 2034         self._inferred_dtype = self._validate(data)
   2035         self._is_categorical = is_categorical_dtype(data)
   2036         self._is_string = data.dtype.name == "string"

~\Anaconda3\envs\tf2\lib\site-packages\pandas\core\strings.py in _validate(data)
   2069         if isinstance(data, ABCMultiIndex):
   2070             raise AttributeError(
-> 2071                 "Can only use .str accessor with Index, not MultiIndex"
   2072             )
   2073 

AttributeError: Can only use .str accessor with Index, not MultiIndex

Ответы [ 3 ]

0 голосов
/ 03 апреля 2020

Я не могу сказать, пытаетесь ли вы переименовать MultiIndex столбцы или MultiIndex имена , поэтому я могу указать, как это сделать для обоих. Я также не смог получить DataFrame из предоставленных вами данных, так что вот фальшивый набор:

>>> arrays = [np.array(['bar 1', 'bar 1', 'baz 2', 'baz 2', 'foo 3', 'foo 3', 'qux 4', 'qux 4']), np.array(['one a', 'two b', 'one a', 'two b', 'one a', 'two b', 'one a', 'two b'])]
>>> df = pd.DataFrame(np.random.randn(8, 4), index=arrays)
>>> df.index
MultiIndex(levels=[['bar 1', 'baz 2', 'foo 3', 'qux 4'], ['one a', 'two b']],
           labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]])
>>> df.index.names
FrozenList([None, None])

Здесь вы создаете новый MultiIndex с пониманием вложенного списка и заменяете нужные символы

>>> new_mi = pd.MultiIndex(levels=[[col.replace(' ', '_') for col in lvl] for lvl in df.index.levels], labels=df.index.labels)
>>> new_mi
MultiIndex(levels=[['bar_1', 'baz_2', 'foo_3', 'qux_4'], ['one_a', 'two_b']],
           labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]])
>>> df.index = new_mi
>>> df.index
MultiIndex(levels=[['bar_1', 'baz_2', 'foo_3', 'qux_4'], ['one_a', 'two_b']],
           labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]])

Если вы пытаетесь изменить имена MultiIndex, просто сделайте это для имен:

# set up names to be strings with spaces
>>> df.index.names = ['name 1', 'name 2']
>>> df.index.names
FrozenList(['name 1', 'name 2'])
# replace spaces with underscore
>>> df.index.names = [_name.replace(' ', '_') for _name in df.index.names]
>>> df.index.names
FrozenList(['name_1', 'name_2'])
0 голосов
/ 04 апреля 2020

Я хотел изменить имена столбцов. Я нашел следующее решение для работы:

arrays = [np.array(['bar 1', 'bar 1', 'baz 2', 'baz 2', 'foo 3', 'foo 3', 'qux 4', 'qux 4']), 
          np.array(['one a', 'two b', 'one a', 'two b', 'one a', 'two b', 'one a', 'two b'])]
dff = pd.DataFrame(np.random.randn(4, 8), columns=arrays)

enter image description here

dff.columns = dff.columns.set_levels((dff.columns.get_level_values(0)).str.replace(' ', '_').unique(), level = 0)

dff.columns = dff.columns.set_levels((dff.columns.get_level_values(1)).str.replace(' ', '_').unique(), level = 1)

enter image description here

0 голосов
/ 03 апреля 2020

Я не могу правильно прочитать ваш JSON, поэтому не могу воспроизвести, но я считаю, что вы должны использовать df.index.names вместо df.columns.

...