2017-02-10 92 views
1

我有一个列表,我想要变成一个数据框,并保持其原始列表中的列表。列表中的列表到数据框中的熊猫

x = [["a", "b", "c"], ["A", "B"], ["AA", "BB", "CC"]] 

我可以与用于这样的循环操作如下:

result = [] 
for id, row in enumerate(x): 
    d = pd.DataFrame({"attr": row, "id": [id]*len(row)}) 
    result.append(d) 
result = pd.concat(result, ignore_index=True) 

或同等发生器表达式:

pd.concat((pd.DataFrame({"attr": row, "id": [id]*len(row)}) 
      for id, row in enumerate(x)), ignore_index=True) 

两个工作正常,产生一个数据帧,如:

id attr 
0 0 a 
1 0 b 
2 0 c 
3 1 A 
4 1 B 
5 2 AA 
6 2 BB 
7 2 CC 

但感觉就像应该有一个更“熊猫式”的方式,而不是使用列表循环追加模式或等效发生器。

我可以使用pandas调用创建上面的数据框,即不使用for循环或python理解吗?

(最好也是一个更快的解决方案:在电影镜头数据集的'流派'上https://grouplens.org/datasets/movielens/这需要4秒钟以平摊每部电影的流派列表,尽管它总共只有20k条目...)

+0

'栈()'就是你正在寻找 –

+0

请确保您标记与绿色对勾最好的答案,使其成为接受的答案。 –

回答

0

在我看来,你需要的是一个快速的方法来扁平化x列表,并创建另一个ID列表。有效的阅读很好的帖子flattening lists

你可以调整基本的扁平列表理解来快速生成你的ID。

x = [["a", "b", "c"], ["A", "B"], ["AA", "BB", "CC"]] 
attr = [attr for sublist in x for attr in sublist] 
id = [id for sublist in [[i]*len(r) for i,r in enumerate(x)] for id in sublist] 
df = pd.DataFrame({'attr': attr, 'id': id }) 
df 
>>> 
    attr id 
0 a 0 
1 b 0 
2 c 0 
3 A 1 
4 B 1 
5 AA 2 
6 BB 2 
7 CC 2 

# Testing the time to flatten 20k nested lists 
import timeit 

setup = ''' 
vals = [[1], [1,2], [1,2,3], [1,2,3,4]]*5000 
lots_of_ids = [attr for sublist in [[i]*len(r) for i,r in enumerate(vals)] for attr in sublist] 
''' 

print min(timeit.Timer(setup=setup).repeat(10)) 
>>> 0.0471019744873 
1

我相信stack()是你在找什么:

pd.DataFrame(x).stack().reset_index().drop('level_1', axis=1)