【问题标题】:Pandas: joining items with same index熊猫:加入具有相同索引的项目
【发布时间】:2016-12-21 23:49:23
【问题描述】:

我有一个 pandas 数据框,它是一个带有值和索引的向量,比如:

row1  10
row1  11
row2  9
row2  8

但是,我想从中创建一个 2x2 矩阵,其中行索引实际上是一个标题(列索引)。像这样:

row1  row2
10    9
11    8

最有效的方法是什么?这个例子是一个简化,但我可能要处理数千个数据点。 pandas 是否有特定的功能可以将具有相同索引的项目连接到表中?

观察:所有索引都有相同数量的条目。

【问题讨论】:

  • 10 和 11(或 9 和 8)的顺序重要吗?

标签: python pandas matrix dataframe


【解决方案1】:

将另一列分配给索引并取消堆叠

s.index = [s.groupby(level=0).cumcount(), s.index]
s.unstack()

0  row1  row2
0    10     9
1    11     8

numpy 的替代方法
还是更慢(等等……)

u, inv = np.unique(s.index.values, return_inverse=True)
data = dict(zip(u, [s.values[g] for g in (np.arange(len(u))[:, None] == inv)]))
pd.DataFrame(data)

【讨论】:

  • 你明白了!谢谢你,先生!
【解决方案2】:

您可以为每个唯一索引创建一个 id 变量,然后将表格转换为宽格式:

df.assign(id = df.groupby([0]).cumcount()).set_index(['id', 0]).unstack(level=1)

#      1
#0  row1    row2
#id     
# 0   10       9
# 1   11       8

【讨论】:

    【解决方案3】:

    在索引上使用groupby获取每个索引的元素列表,使用to_dict获取字典,然后使用pd.DataFrame构造函数:

    pd.DataFrame(df.groupby(level=0)['column_name'].apply(list).to_dict())
    

    如果你有一个系列,比如s,而不是 DataFrame,你不需要提供列名:

    pd.DataFrame(s.groupby(level=0).apply(list).to_dict())
    

    结果输出:

       row1  row2
    0    10     9
    1    11     8
    

    时间

    使用以下设置生成更大的样本数据,假设输入数据是一个DataFrame:

    n = 10**6
    df = pd.DataFrame(np.random.random(size=n), index=['row1', 'row2']*(n//2))
    
    def pir2(s):
        s.index = [s.groupby(level=0).cumcount(), s.index]
        return s.unstack()
    

    我得到以下时间:

    %timeit pd.DataFrame(df.groupby(level=0)[0].apply(list).to_dict())
    1 loop, best of 3: 210 ms per loop
    
    %timeit pir2(df.copy())
    1 loop, best of 3: 486 ms per loop
    
    %timeit df.assign(id = df.groupby([0]).cumcount()).set_index(['id', 0]).unstack(level=1)
    1 loop, best of 3: 1.34 s per loop
    

    【讨论】:

    • @piRSquared -- 复杂性方面,你推荐这个答案吗?确实,root 做得很好。
    • @GuilhermeNazarethdeSouza 这是一个品味问题。如果您了解 root 做了什么(我认为这并不复杂),我会使用这个答案。也就是说,我受到启发,想在我的帖子中添加另一个答案。
    【解决方案4】:

    而且使用@root 的例子稍微快一点:)

    pd.DataFrame({name:group.values for name, group in df.groupby(level=0)[0]})
    

    时间安排:

    %timeit pd.DataFrame({name:group.values for name, group in df.groupby(level=0)[0]})
    10 loops, best of 3: 73.6 ms per loop
    
    %timeit pd.DataFrame(df.groupby(level=0)[0].apply(list).to_dict())
    1 loop, best of 3: 249 ms per loop
    

    【讨论】:

      猜你喜欢
      • 2018-12-25
      • 2017-01-31
      • 2023-03-24
      • 1970-01-01
      • 2020-02-21
      • 2021-08-23
      • 2021-02-13
      • 2016-10-02
      • 1970-01-01
      相关资源
      最近更新 更多