【问题标题】:How do I change or access pandas MultiIndex column headers?如何更改或访问 pandas MultiIndex 列标题?
【发布时间】:2016-09-19 01:18:45
【问题描述】:

我有以下 Pandas DataFrame,但在更新列标题值或轻松访问标题值时遇到问题(例如,在标题的 (lon,lat) 位置绘制时间)。

df = pd.DataFrame(columns = ["id0", "id1", "id2"])
df.loc[2012]= [24, 25, 26]
df.loc[2013]= [28, 28, 29]
df.loc[2014]= [30, 31, 32]

df.columns = pd.MultiIndex.from_arrays([df.columns, [66,67,68], [110,111,112]],
                                       names=['id','lat','lon'])

然后看起来像这样:

>>> df
id     id0   id1   id2
lat     66    67    68
lon    110   111   112
2012  24.0  25.0  26.0
2013  28.0  28.0  29.0
2014  30.0  31.0  32.0

我希望能够根据(lon,lat) 调整df['id0']plot(df.ix[2014]) 的纬度或经度,但位于(x,y) 位置。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    您可以使用df.columns.get_level_values('lat') 来获取索引对象。这将返回索引的副本,因此您无法扩展此方法来修改坐标。

    但是,您可以直接访问关卡并使用此解决方法就地修改它们。

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(columns = ["id0", "id1", "id2"])
    df.loc[2012]= [24, 25, 26]
    df.loc[2013]= [28, 28, 29]
    df.loc[2014]= [30, 31, 32]
    
    df.columns = pd.MultiIndex.from_arrays([df.columns, [66,67,68], [110,111,112]],
                                           names=['id','lat','lon'])
    
    ids = df.columns.get_level_values('id')
    id_ = 'id0'
    column_position = np.where(ids.values == id_)
    
    new_lat = 90
    new_lon = 0
    
    df.columns._levels[1].values[column_position] = new_lat
    df.columns._levels[2].values[column_position] = new_lon
    

    【讨论】:

      【解决方案2】:

      您通过元组访问MultiIndex。例如:

      df.loc[:, ('id0', 66, 110)]
      

      但是,您可能希望在不指定 id 的情况下通过 lon/lat 访问,或者您可能会有多个 id。在这种情况下,您可以做 2 件事。

      首先,使用pd.IndexSlice 允许有用的MultiIndex 切片:

      df.loc[:, pd.IndexSlice[:, 66, 110]]
      

      第二:

      df.stack(0).loc[:, (66, 110)].dropna().unstack()
      

      这比较麻烦,但可能有用。

      最后,你提到的最后一件事。对于具有 lon/lat 的特定行。

      df.loc[2014, pd.IndexSlice[:, 66, 110]]
      

      【讨论】:

      • 据我了解,OP想要修改多索引。
      • 是的,我想修改 lon,lat。但除此之外,我的数据框有 ~1000 次(行)和 ~500,000 个 ID(列),每个 ID 都有一个 lon 和 lat。如何跟踪每列的位置? pd.IndexSlice 语法不起作用,因为有 500,000 个项目。有没有像df.loc[2014, 'lat'] 这样的语法来获取所有纬度?
      • 您的示例表明2014 将对应于所有lats。在这种情况下,您可以使用df.columns.get_level_values('lat')。另外,鉴于您的问题的规模,也许您应该考虑转置?可能会在矢量化操作上获得更大的加速。
      • 我会尝试转置。我认为时间序列需要是索引列。
      • @YakymPirozhenko 如果您将您的评论作为答案,我可以接受。
      猜你喜欢
      • 2019-01-26
      • 2016-08-16
      • 2023-03-14
      • 1970-01-01
      • 2016-09-18
      • 1970-01-01
      • 2019-07-17
      • 1970-01-01
      • 2012-10-13
      相关资源
      最近更新 更多