मैंने cxrodgers उत्तर से थोड़ा सा कार्य किया , जो IMHO सबसे अच्छा समाधान है क्योंकि यह शुद्ध रूप से किसी भी डेटा फ्रेम या श्रृंखला से स्वतंत्र सूचकांक पर काम करता है।
मेरे द्वारा जोड़ा गया एक फिक्स है: to_frame()विधि इंडेक्स स्तरों के लिए नए नामों का आविष्कार करेगी जिनके पास एक नहीं है। जैसे कि नए सूचकांक में ऐसे नाम होंगे जो पुराने सूचकांक में मौजूद नहीं हैं। इस नाम-परिवर्तन को वापस करने के लिए मैंने कुछ कोड जोड़े।
नीचे कोड है, मैंने इसे कुछ समय के लिए उपयोग किया है और यह ठीक काम करने लगता है। यदि आपको कोई समस्या या किनारे के मामले मिलते हैं, तो मैं अपने उत्तर को समायोजित करने के लिए बहुत बाध्य हूं।
import pandas as pd
def _handle_insert_loc(loc: int, n: int) -> int:
"""
Computes the insert index from the right if loc is negative for a given size of n.
"""
return n + loc + 1 if loc < 0 else loc
def add_index_level(old_index: pd.Index, value: Any, name: str = None, loc: int = 0) -> pd.MultiIndex:
"""
Expand a (multi)index by adding a level to it.
:param old_index: The index to expand
:param name: The name of the new index level
:param value: Scalar or list-like, the values of the new index level
:param loc: Where to insert the level in the index, 0 is at the front, negative values count back from the rear end
:return: A new multi-index with the new level added
"""
loc = _handle_insert_loc(loc, len(old_index.names))
old_index_df = old_index.to_frame()
old_index_df.insert(loc, name, value)
new_index_names = list(old_index.names)
new_index_names.insert(loc, name)
new_index = pd.MultiIndex.from_frame(old_index_df, names=new_index_names)
return new_index
यह निम्नलिखित unittest कोड पारित किया:
import unittest
import numpy as np
import pandas as pd
class TestPandaStuff(unittest.TestCase):
def test_add_index_level(self):
df = pd.DataFrame(data=np.random.normal(size=(6, 3)))
i1 = add_index_level(df.index, "foo")
self.assertEqual([None, None], i1.names)
self.assertTrue(np.all(i1.get_level_values(0) == "foo"))
self.assertTrue(np.all(i1.get_level_values(1) == df.index))
i2 = add_index_level(i1, ["x", "y"]*3, name="xy", loc=2)
i3 = add_index_level(i2, ["a", "b", "c"]*2, name="abc", loc=-1)
self.assertEqual([None, None, "xy", "abc"], i3.names)
self.assertTrue(np.all(i3.get_level_values(0) == "foo"))
self.assertTrue(np.all(i3.get_level_values(1) == df.index))
self.assertTrue(np.all(i3.get_level_values(2) == ["x", "y"]*3))
self.assertTrue(np.all(i3.get_level_values(3) == ["a", "b", "c"]*2))
axis=1, क्योंकिdf.columnsइसमें इंडेक्स की तरह "सेट_इंडेक्स" विधि नहीं है, जो हमेशा मुझे परेशान करता है।