2017-02-10 135 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)