熊猫:加入具有相同索引的项目

时间:2016-12-21 23:49:23

标签: python pandas matrix dataframe

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

row1  10
row1  11
row2  9
row2  8

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

row1  row2
10    9
11    8

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

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

4 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

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

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 :(得分:2)

在索引上使用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

答案 3 :(得分:2)

使用@ 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