Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何最好地使用pandas.DataFrame.pivot?_Python_Pandas - Fatal编程技术网

Python 如何最好地使用pandas.DataFrame.pivot?

Python 如何最好地使用pandas.DataFrame.pivot?,python,pandas,Python,Pandas,我正在尝试将数据帧从键行、值行转换为以键为列、值为单元格的表。例如: 输入带有键、值的数据帧: >>>df = pd.DataFrame([['TIME', 'VAL1', 'VAL2', 'VAL3', 'TIME', 'VAL1', 'VAL2', 'VAL3'], ["00:00:01",1,2,3,"00:00:02", 1,2,3]]).T 0 1 0

我正在尝试将数据帧从键行、值行转换为以键为列、值为单元格的表。例如:

输入带有键、值的数据帧:

>>>df = pd.DataFrame([['TIME', 'VAL1', 'VAL2', 'VAL3', 
                       'TIME', 'VAL1', 'VAL2', 'VAL3'],
                      ["00:00:01",1,2,3,"00:00:02", 1,2,3]]).T

    0       1
0   TIME    00:00:01
1   VAL1    1
2   VAL2    2
3   VAL3    3
4   TIME    00:00:02
5   VAL1    1
6   VAL2    2
7   VAL3    3
我希望它看起来像:

TIME      VAL1 VAL2 VAL3
00:00:01  1    2    3
00:00:02  1    2    3
我几乎可以通过pivot获得我想要的:

>>>df.pivot(columns=0, values=1)
    TIME        VAL1    VAL2    VAL3
0   00:00:01    None    None    None
1   None        1       None    None
2   None        None    2       None
3   None        None    None    3
4   00:00:02    None    None    None
5   None        1       None    None
6   None        None    2       None
7   None        None    None    3
我可以合并这些行以得到我想要的:

>>> df.pivot(columns=0, values=1).ffill().drop_duplicates(subset='TIME',
                                                          keep='last').set_index('TIME')
TIME      VAL1 VAL2 VAL3
00:00:01  1    2    3
00:00:02  1    2    3
但这似乎是一种相当尴尬的方式,因为这样做会浪费大量内存用于大型数据集。有没有更简单的方法

我厌倦了看
pd.DataFrame.from_items()
pd.DataFrame.from_records()
,但没有成功。

您需要一个“ID”变量来指示哪些行一起。在所需的输出中,您隐式地假设由4行组成的每个块都应该成为一行,但pandas不会这样假设,因为通常情况下,旋转应该能够将非连续行组合在一起。要成为新数据帧中单行的每组行必须具有某些共享值

如果您的数据实际上只是四行数据块,您可以创建如下ID变量:

df['ID'] = np.arange(len(df))//4
您可以看到,ID变量现在标记了应分组的行:

>>> df
      0         1  ID
0  TIME  00:00:01   0
1  VAL1         1   0
2  VAL2         2   0
3  VAL3         3   0
4  TIME  00:00:02   1
5  VAL1         1   1
6  VAL2         2   1
7  VAL3         3   1
然后使用这个新列作为透视图的“索引”

>>> df.pivot(index="ID", columns=0, values=1)
0       TIME VAL1 VAL2 VAL3
ID                         
0   00:00:01    1    2    3
1   00:00:02    1    2    3

另一种方法是:

In [65]: df
Out[65]: 
      0         1
0  TIME  00:00:01
1  VAL1         1
2  VAL2         2
3  VAL3         3
4  TIME  00:00:02
5  VAL1         1
6  VAL2         2
7  VAL3         3

In [66]: newdf = pd.concat([df[df[0] == x].reset_index()[1] for x in df[0].unique()], axis=1)

In [67]: newdf.columns = df[0].unique()

In [68]: newdf
Out[68]: 
       TIME VAL1 VAL2 VAL3
0  00:00:01    1    2    3
1  00:00:02    1    2    3

您可以使用defaultdict在DataFrame构造函数中正常工作:

import collections
keys = ['TIME', 'VAL1', 'VAL2', 'VAL3', 'TIME', 'VAL1', 'VAL2', 'VAL3']
values = ["00:00:01",1,2,3,"00:00:02", 1,2,3]

d = collections.defaultdict(list)
for k, v in zip(keys, values):
    d[k].append(v)

'''
d looks like this:
defaultdict(list,
            {'TIME': ['00:00:01', '00:00:02'],
             'VAL1': [1, 1],
             'VAL2': [2, 2],
             'VAL3': [3, 3]})'''

df = pd.DataFrame(d)
df
Out: 
       TIME  VAL1  VAL2  VAL3
0  00:00:01     1     2     3
1  00:00:02     1     2     3
Nehal J Wani的替代方案,如果您无法访问这些列表:

df = pd.DataFrame([['TIME', 'VAL1', 'VAL2', 'VAL3', 
                   'TIME', 'VAL1', 'VAL2', 'VAL3'],
                  ["00:00:01",1,2,3,"00:00:02", 1,2,3]]).T

d = collections.defaultdict(list)
for k, v in zip(df[0], df[1]):
    d[k].append(v)

嗯,我想我现在明白了这个枢轴函数应该如何工作了。pivot会在内存中创建数据的新副本吗?@Kyle:是的,它会。当VALx不是固定数量的行,而是在不同的时间段之间变化时,请使用它:
df['ID']=(df.index==“TIME”).cumsum()
有趣的想法。基本上是遍历键列的唯一值,选择这些值,并将这些列合并在一起?@Kyle是的,的确!问题是如何从原始数据帧中获取经过整形的数据帧,而不是如何直接从一些外部数据创建经过整形的数据帧。@BrenBarn OP的尝试,如
pd.DataFrame.from\u items()
pd.DataFrame.from\u records()
就是朝这个方向发展的,所以我认为这可能是一个解决方案。