包含iterab的拆分数据帧列

2024-04-18 17:06:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个DataFrame,其中一列以列表或元组的形式(总是相同的长度)包含一些顺序数据,我的目标是将此列拆分为几个新列,理想情况下更新一个现有列。你知道吗

这是一个最小的例子

from pandas import DataFrame, concat

data = DataFrame({"label": [a for a in "abcde"], "x": range(5)})
print(data)

  label  x
0     a  0
1     b  1
2     c  2
3     d  3
4     e  4

虚构的方法是,使用不存在的函数splittuple

data[["x", "x2"]] = data["x"].apply(lambda x: (x, x*2)).splittuple(expand = True)

导致

  label  x  x2
0     a  0  0
1     b  1  2
2     c  2  4
3     d  3  6
4     e  4  8

我当然可以这样做,尽管解决方法有点麻烦

newdata = DataFrame(data["x"].apply(lambda x: (x, x*2)).tolist(), columns = ["x", "x2"])
data.drop("x", axis = 1, inplace = True)
data = concat((data, newdata), axis = 1)
print(data)

  label  x  x2
0     a  0   0
1     b  1   2
2     c  2   4
3     d  3   6
4     e  4   8

另一个更丑陋的解决方案

data[["x", "x2"]] = 
  data["x"].apply(lambda x: "{} {}".format(x, x*2)).str.split(expand = True).astype(int)

你能推荐一种更优雅的方法来进行这种转换吗?你知道吗


Tags: 方法lambdatruedataframe列表datalabelexpand
1条回答
网友
1楼 · 发布于 2024-04-18 17:06:36

这是可能的,但是用applySeries不是那么快:

tup = data["x"].apply(lambda x: (x, x*2))
data[["x", "x2"]] = tup.apply(pd.Series)

print (data)
  label  x  x2
0     a  0   0
1     b  1   2
2     c  2   4
3     d  3   6
4     e  4   8

更快的是使用DataFrame构造函数:

tup = data["x"].apply(lambda x: (x, x*2))
data[["x", "x2"]] = pd.DataFrame(tup.values.tolist())
print (data)
  label  x  x2
0     a  0   0
1     b  1   2
2     c  2   4
3     d  3   6
4     e  4   8

时间安排:

data = pd.DataFrame({"label": [a for a in "abcde"], "x": range(5)})
data = pd.concat([data]*1000).reset_index(drop=True)
tup = data["x"].apply(lambda x: (x, x*2))


data[["x", "x2"]] = tup.apply(pd.Series)
data[["y", "y2"]] = pd.DataFrame(tup.values.tolist())
print (data)

In [266]: %timeit data[["x", "x2"]] = tup.apply(pd.Series)
1 loop, best of 3: 836 ms per loop

In [267]: %timeit data[["y", "y2"]] = pd.DataFrame(tup.values.tolist())
100 loops, best of 3: 3.1 ms per loop

相关问题 更多 >