如果你想留在纯熊猫中,你可以添加一个棘手的groupby
and apply
如果您不计算列重命名,则最终会归结为单行。
In [1]: import pandas as pd
In [2]: d = {'date': ['4/1/11', '4/2/11'], 'ts': [[pd.Timestamp('2012-02-29 00:00:00'), pd.Timestamp('2012-03-31 00:00:00'), pd.Timestamp('2012-04-25 00:00:00'), pd.Timestamp('2012-06-30 00:00:00')], [pd.Timestamp('2014-01-31 00:00:00')]]}
In [3]: df = pd.DataFrame(d)
In [4]: df.head()
Out[4]:
date ts
0 4/1/11 [2012-02-29 00:00:00, 2012-03-31 00:00:00, 201...
1 4/2/11 [2014-01-31 00:00:00]
In [5]: df_new = df.groupby('date').ts.apply(lambda x: pd.DataFrame(x.values[0])).reset_index().drop('level_1', axis = 1)
In [6]: df_new.columns = ['date','ts']
In [7]: df_new.head()
Out[7]:
date ts
0 4/1/11 2012-02-29
1 4/1/11 2012-03-31
2 4/1/11 2012-04-25
3 4/1/11 2012-06-30
4 4/2/11 2014-01-31
由于目标是获取列的值(在本例中为日期)并对您打算从列表中创建的多行的所有值重复该值,因此考虑 pandas 索引很有用。
我们希望日期成为新行的单个索引,因此我们使用groupby
它将所需的行值放入索引中。然后在该操作中我只想分割这个日期的列表,这就是apply
会为我们做的。
我路过apply
一只熊猫Series
它由一个列表组成,但我可以通过.values[0]
这推动了唯一的一行Series
到具有单个条目的数组。
要将列表转换为一组将传递回索引日期的行,我可以将其设为DataFrame
。这会带来额外索引的惩罚,但我们最终会放弃它。我们可以将其本身作为索引,但这会排除重复值。
一旦将其传回,我就有了一个多索引,但我可以通过以下方式将其强制转换为我们想要的行格式reset_index
。然后我们只需删除不需要的索引即可。
听起来很复杂,但实际上我们只是利用 pandas 函数的自然行为来避免显式迭代或循环。
速度方面这往往相当不错,因为它依赖于apply
任何适用的并行化技巧apply
在这里工作。
或者,如果您希望它对多个日期具有鲁棒性,每个日期都有一个嵌套列表:
df_new = df.groupby('date').ts.apply(lambda x: pd.DataFrame([item for sublist in x.values for item in sublist]))
此时,单行代码会变得密集,您可能应该将其放入一个函数中。