【问题标题】:How to reindex efficiently a DataFrame to fill holes in the index list?如何有效地重新索引 DataFrame 以填补索引列表中的漏洞?
【发布时间】:2018-05-15 23:02:04
【问题描述】:

我有这个数据框:

          value
L1 L2 L3       
11 21 31      1
      32      2
      34      3
   23 31      4
      33      5
      34      6
12 21 32      7

在这个 DataFrame 中,(L1, L2) 是一个 ID 元组,L3 是一个星期数。我想在我的 DataFrame 中添加一些行,以便为所有具有默认值的元组提供所有可能的周数:

          value
L1 L2 L3       
11 21 31      1
      32      2
      33      0
      34      3
   23 31      4
      32      0
      33      5
      34      6
12 21 31      0
      32      7
      33      0
      34      0

为了得到这个DataFrame,我得到了唯一元组(L1,L2)的列表和L3的所有值的列表来创建一个新的MultiIndex并重新索引我的DataFrame:

# Get all tuples (L1,L2)
l12_set = set(df.index.droplevel(2).tolist())

# Get all L3
l3_set = set(df.index.droplevel([0,1]).tolist())

index_array_l1 = np.array([], int)
index_array_l2 = np.array([], int)
index_array_l3 = np.array([], int)

# Creation of the index
for l1, l2 in l12_set:
    for l3 in l3_set:
        index_array_l1 = np.append(index_array_l1, l1)
        index_array_l2 = np.append(index_array_l2, l2)
        index_array_l3 = np.append(index_array_l3, l3)

index_array = np.array([index_array_l1, index_array_l2, index_array_l3])
multi_index = pd.MultiIndex.from_arrays(index_array, names=['L1', 'L2', 'L3'])

df = df.reindex(multi_index, fill_value=0)

问题是这个方法很长一个很大的DataFrame(数百万行)。我想知道 pandas 库中是否已经实现了快速方法(或者是否有更快的方法)。

【问题讨论】:

    标签: python pandas dataframe optimization


    【解决方案1】:

    通过使用unstackstack

    df.unstack().stack(dropna=False).fillna(0).astype(int)
    Out[433]: 
              value
    L1 L2 L3       
    11 21 31      1
          32      2
          33      0
          34      3
       23 31      4
          32      0
          33      5
          34      6
    12 21 31      0
          32      7
          33      0
          34      0
    

    【讨论】:

    • df.unstack(fill_value=0).stack(dropna=False)
    • 其实我忘了。如果您使用fill_value=0,则不需要dropna=Falsedf.unstack(fill_value=0).stack()
    【解决方案2】:
    u = pd.unique([t[:2] for t in df.index.values])
    l2 = df.index.levels[2]
    df.reindex([t + (i,) for t in u for i in l2], fill_value=0)
    
              value
    L1 L2 L3       
    11 21 31      1
          32      2
          33      0
          34      3
       23 31      4
          32      0
          33      5
          34      6
    12 21 31      0
          32      7
          33      0
          34      0
    

    【讨论】:

    • @jezrael 已修复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 2017-06-02
    • 2017-12-22
    • 2012-10-09
    相关资源
    最近更新 更多