我有以下df
,
A id
[ObjectId('5abb6fab81c0')] 0
[ObjectId('5abb6fab81c3'),ObjectId('5abb6fab81c4')] 1
[ObjectId('5abb6fab81c2'),ObjectId('5abb6fab81c1')] 2
我想在A
中展平每个列表,并将相应的id
分配给列表中的每个元素,例如
A id
ObjectId('5abb6fab81c0') 0
ObjectId('5abb6fab81c3') 1
ObjectId('5abb6fab81c4') 1
ObjectId('5abb6fab81c2') 2
ObjectId('5abb6fab81c1') 2
答案 0 :(得分:2)
这可能不是最优雅的解决方案,但它确实有效。这里的想法是循环遍历df
(这就是为什么这可能是一个低效的解决方案),然后遍历列A
中的每个列表,将每个项目和id
附加到新的名单。然后将这两个新列表转换为新的DataFrame。
a_list = []
id_list = []
for index, a, i in df.itertuples():
for item in a:
a_list.append(item)
id_list.append(i)
df1 = pd.DataFrame(list(zip(alist, idlist)), columns=['A', 'id'])
正如我所说,不优雅,但它完成了工作。可能至少有一种更好的方法来优化它,但希望它能让你前进。
我想到了我的和温的代码之间的时间比较,只是出于好奇。这两个变量是列A
的长度,以及列A
中列表条目的长度。我运行了一堆测试用例,每次迭代数量级。例如,我从A
长度= 10开始,并在每个步骤中迭代通过随机化的A
条目列表长度1-10,1-100 ... 1-1,000,000来运行到1,000,000。我找到了以下内容:
A
个长度)。随机列表长度达到~1,000的障碍,Wen的代码接管速度。这对我来说是一个巨大的惊喜!我完全希望我的代码每次都丢失。A
的长度通常无关紧要 - 它只是线性增加整体执行时间。它改变结果的唯一情况是A
长度= 10.在这种情况下,无论列表长度如何,我的代码运行得更快(对我来说也很奇怪)。 结论:如果A
中的列表条目长度为几百个元素(或更少),我的代码就可以了。但是,如果您正在使用大量数据集,请使用Wen的!另外值得注意的是,当你达到1,000,000的障碍时,两种方法都会大幅减速。我正在使用一台功能相当强大的计算机,每台计算机都要花费几分钟时间(它实际上在A
长度= 1,000,000,列表长度= 1,000,000的情况下崩溃)。
答案 1 :(得分:2)
我认为评论来自这个问题?你可以使用我的original post或者这个
df.set_index('id').A.apply(pd.Series).stack().reset_index().drop('level_1',1)
Out[497]:
id 0
0 0 1.0
1 1 2.0
2 1 3.0
3 1 4.0
4 2 5.0
5 2 6.0
或
pd.DataFrame({'id':df.id.repeat(df.A.str.len()),'A':df.A.sum()})
Out[498]:
A id
0 1 0
1 2 1
1 3 1
1 4 1
2 5 2
2 6 2
答案 2 :(得分:0)
可以使用此功能进行平整和不平整
def flatten(df, col):
col_flat = pd.DataFrame([[i, x] for i, y in df[col].apply(list).iteritems() for x in y], columns=['I', col])
col_flat = col_flat.set_index('I')
df = df.drop(col, 1)
df = df.merge(col_flat, left_index=True, right_index=True)
return df
展平:
def unflatten(flat_df, col):
flat_df.groupby(level=0).agg({**{c:'first' for c in flat_df.columns}, col: list})
展开后,除了列顺序外,我们得到相同的数据框:
(df.sort_index(axis=1) == unflatten(flatten(df)).sort_index(axis=1)).all().all()
>> True
要创建唯一索引,可以在展平后调用reset_index