我有一个以下数据框,它是使用代码获得的:
df1=df.groupby('id')['x,y'].apply(lambda x: rdp(x.tolist(), 5.0)).reset_index()
参考here
获得的结果数据框:
id x,y
0 1 [(0, 0), (1, 2)]
1 2 [(1, 3), (1, 2)]
2 3 [(2, 5), (4, 6)]
是否有可能得到这样的东西:
id x,y
0 1 (0, 0)
1 1 (1, 2)
2 2 (1, 3)
3 2 (1, 2)
4 3 (2, 5)
5 3 (4, 6)
这里,作为前一个df的结果获得的坐标列表将根据各自的ID分成新行。
答案 0 :(得分:5)
您可以将DataFrame
构造函数与stack
:
df2 = pd.DataFrame(df1['x,y'].values.tolist(), index=df1['id'])
.stack()
.reset_index(level=1, drop=True)
.reset_index(name='x,y')
print (df2)
id x,y
0 1 (0, 0)
1 1 (1, 2)
2 2 (1, 3)
3 2 (1, 2)
4 3 (2, 5)
5 3 (4, 6)
numpy
解决方案使用numpy.repeat
lengths
str.len
之后numpy.ndarray.sum
列的{{3}}列{@ 3}}列为{{3}}:
x,y
<强>计时强>:
df2 = pd.DataFrame({'id': np.repeat(df1['id'].values, df1['x,y'].str.len()),
'x,y': df1['x,y'].values.sum()})
print (df2)
id x,y
0 1 (0, 0)
0 1 (1, 2)
1 2 (1, 3)
1 2 (1, 2)
2 3 (2, 5)
2 3 (1, 9)
2 3 (4, 6)
答案 1 :(得分:2)
'id'
列
str.len
方法快速计算每个元素的子列表中的元素数量。这很方便,因为我们可以直接将此结果传递给repeat
的{{1}}方法,该方法将从我们传递的长度中重复每个元素相应的数量。df1['id']
列
'x,y'
将所有子列表推送到一起。但是,在这种情况下,子列表是元组列表。 np.concatenate
不会将这些视为对象列表。相反,我使用np.concatenate
方法,它将在列表上使用基础sum
方法,而这些方法将依次连接。sum
如果我们坚持pandas
,我们可以保持代码清洁
将pandas
与repeat
和str.len
sum
pd.DataFrame({
'id': df1['id'].repeat(df1['x,y'].str.len()),
'x,y': df1['x,y'].sum()
})
id x,y
0 1 (0, 0)
0 1 (1, 2)
1 2 (1, 3)
1 2 (1, 2)
2 3 (2, 5)
2 3 (4, 6)
我们可以通过使用底层的numpy数组和等效的numpy方法来加速这种方法
注意:这是等效的逻辑!
numpy
我们可以通过跳过pd.DataFrame({
'id': df1['id'].values.repeat(df1['x,y'].str.len()),
'x,y': df1['x,y'].values.sum()
})
方法并使用列表理解来计算长度来加快速度。
str.len
小数据
pd.DataFrame({
'id': df1['id'].values.repeat([len(w) for w in df1['x,y'].values.tolist()]),
'x,y': df1['x,y'].values.sum()
})
更大的数据
%%timeit
pd.DataFrame({
'id': df1['id'].values.repeat([len(w) for w in df1['x,y'].values.tolist()]),
'x,y': df1['x,y'].values.sum()
})
1000 loops, best of 3: 351 µs per loop
%%timeit
pd.DataFrame({
'id': df1['id'].repeat(df1['x,y'].str.len()),
'x,y': df1['x,y'].sum()
})
1000 loops, best of 3: 590 µs per loop
%%timeit
pd.DataFrame({'id': np.repeat(df1['id'].values, df1['x,y'].str.len()),
'x,y': df1['x,y'].values.sum()})
1000 loops, best of 3: 498 µs per loop