从(row,col,values)元组列表构造pandas DataFrame


81

我有一个元组列表,例如

data = [
('r1', 'c1', avg11, stdev11),
('r1', 'c2', avg12, stdev12),
('r2', 'c1', avg21, stdev21),
('r2', 'c2', avg22, stdev22)
]

我想将它们放入一个熊猫数据框,其中第一行命名为行,第二列命名为列。看来,处理行名称的方法类似,pandas.DataFrame([x[1:] for x in data], index = [x[0] for x in data])但如何处理列以获得2x2矩阵(前一组的输出为3x4)?是否还有一种更智能的方式来处理行标签,而不是显式地忽略它们?

编辑似乎我将需要2个数据框-一个用于平均值,一个用于标准差,对吗?还是可以在每个“单元格”中存储值列表?



2
@EMS一点也不。我看到了这个问题,他不需要2D透视。
gt6989b 2013年

我不同意-我认为您只是不熟悉在DataFrame中堆叠数据的正确方法。通常,您希望将第1列和第2列中的信息用作索引,因此您可以通过任一列快速搜索数据。第2列中的内容不属于列名称,但是即使它们属于列名称,这也是与帖子标题完全不同的问题。我想编辑标题可能会有所帮助(尽管我仍然认为这不是一个有意义的问题)。
2013年

1
@ely,gt6989b我将其改名为“ ...(来自(row,col,values)的元组列表”)以明确说明为什么这不是“ ... from元组”的副本
smci

Answers:


65

您可以在创建后旋转DataFrame:

>>> df = pd.DataFrame(data)
>>> df.pivot(index=0, columns=1, values=2)
# avg DataFrame
1      c1     c2
0               
r1  avg11  avg12
r2  avg21  avg22
>>> df.pivot(index=0, columns=1, values=3)
# stdev DataFrame
1        c1       c2
0                   
r1  stdev11  stdev12
r2  stdev21  stdev22

3
带有索引的行0和带有名称的列1不是很漂亮……
drevicko

49

我认为最好保留数据原样:

df = pandas.DataFrame(data, columns=['R_Number', 'C_Number', 'Avg', 'Std'])

# Possibly also this if these can always be the indexes:
# df = df.set_index(['R_Number', 'C_Number'])

然后说起来有点直觉

df.set_index(['R_Number', 'C_Number']).Avg.unstack(level=1)

这样就隐含了您要重塑平均值或标准偏差。仅仅使用pivot,它就完全基于列约定来确定您要重塑的语义实体。


1
+1,有用的明确性。我对二维表特别感兴趣-允许我搜索按行列表和列列表索引的值,以及分别访问每个维。您可以使用堆叠数据吗?
gt6989b 2013年

2
是的 堆叠数据要好得多。想一想关系数据库表,就像在SQL中一样。您不会把整个专栏吹成一堆重复的专栏吗?这仅应在特殊情况下发生(我认为这是从高到宽的模式)。通常,您将多个列视为索引,并通过部分绑定其中一个索引列或全部绑定它们以获得特定记录来进行选择。
2013年

2
因此,根据您的情况,例如,在将索引设置为be之后[R_Number, C_Number],就可以执行操作df.ix[('r1','c2')]。或者,您可以将它们都保留为常规列并使用逻辑索引:df[(df.R_Number == 'r1') & (df.C_Number == 'c2')]
2013年

2
通常,要做的主要用例pivot是格式化表格时,使其可以在屏幕上很好地打印,或者可以很好地导出到HTML,LaTeX或.csv等。就像格式化将要用于演示或文章提交的表格一样。否则,就有效地处理数据而言,您希望在可能的情况下将其作为多索引(例如数据库表的键),或者至少将其作为重复的列,以便可以进行高效的索引和联接等。但是您不能想要将它们吹散到自己的列中。
2013年

35

这是我想到这个问题时希望看到的:

#!/usr/bin/env python

import pandas as pd


df = pd.DataFrame([(1, 2, 3, 4),
                   (5, 6, 7, 8),
                   (9, 0, 1, 2),
                   (3, 4, 5, 6)],
                  columns=list('abcd'),
                  index=['India', 'France', 'England', 'Germany'])
print(df)

         a  b  c  d
India    1  2  3  4
France   5  6  7  8
England  9  0  1  2
Germany  3  4  5  6

您看错了问题。问题中最初提供的数据已经为每个问题记录具有行和列标签。
gt6989b

11
@ gt6989b不,我没有。我没有尝试回答原始问题,但是人们(可能)在进入此页面时遇到的问题。
马丁·托马

8
@MartinThoma谢谢,的确是我在此页面上寻找的东西。
ssword
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.