2017-09-03 23 views
2

轉換成元組從衆多的列行的熊貓我有一本字典是這樣的:數據框中

data = {'function_name': ['func1', 'func2', 'func3'], 
     'argument': [('func1_arg1', 'func1_arg2'), 
        ('func2_arg1',), 
        ('func3_arg1', 'func3_arg2', 'func3_arg3')], 
     'A': ['value_a1', 'value_a2', 'value_a3'], 
     'B': 'b', 
     'types': [('func1_type1', 'func1_type2'), 
        ('func2_type1',), 
        ('func3_type1', 'func3_type2', 'func3_type3')]} 

我想將其轉換成數據幀的大熊貓,並使它看起來像這樣:

function_name argument types   A   B 

func1   func1_arg1 func1_type1 value_a1 b 
func1   func1_arg2 func1_type2 value_a1 b 
func2   func2_arg1 func2_type1 value_a2 b 
func3   func3_arg1 func3_type1 value_a3 b 
func3   func3_arg2 func3_type2 value_a3 b 
func3   func3_arg3 func3_type3 value_a3 b 

當它從here如下是否會有元組的一列,我會做到這一點:

import pandas as pd 


data_frame = pd.DataFrame(data) 
new_frame = data_frame.set_index(['function_name','A','B'])['argument'].apply(pd.Series).stack().to_frame('argument').reset_index().drop('level_3',1) 

但是,如果我有幾列斑點,我該如何去做呢?

編輯

似乎是與認可的解決方案有點問題。也就是說,如果存在一個完全由None s組成的斑點列或只是空元組,則在形成new_frame的過程中,它們將被丟棄。是否有可能讓大熊貓避免丟棄列。

最初的數據是這樣的:

data = {'function_name': ['func1', 'func2', 'func3'], 
     'argument': [('func1_arg1', 'func1_arg2'), 
        ('func2_arg1',), 
        ('func3_arg1', 'func3_arg2', 'func3_arg3')], 
     'A': ['value_a1', 'value_a2', 'value_a3'], 
     'B': 'b', 
     'types': [('func1_type1', 'func1_type2'), 
        ('func2_type1',), 
        ('func3_type1', 'func3_type2', 'func3_type3')], 
     'info': [(None, None), (None,), (None, None, None)]} 

'信息' 列可能是[(),(),()],結果仍然是一樣的。

回答

3

由於有多列擴展我不認爲這可以在單行,但你可以使用與pd.DataFrame構造函數應用。 stack方法的默認值爲True,因此將其設置爲false以保留None值。即

index = ['function_name','A','B'] 
new_frame = data_frame.set_index(index) 
      .apply(lambda x:pd.DataFrame(x.values.tolist()).stack(dropna=False),1) 
      .stack(dropna=False).reset_index().drop('level_3',1) 
new_frame.columns = index + [x for x in data_frame.columns if x not in index] 
 
    function_name A  B argument   types 
0 func1 value_a1  b func1_arg1 func1_type1 
1 func1 value_a1  b func1_arg2 func1_type2 
2 func2 value_a2  b func2_arg1 func2_type1 
3 func3 value_a3  b func3_arg1 func3_type1 
4 func3 value_a3  b func3_arg2 func3_type2 
5 func3 value_a3  b func3_arg3 func3_type3 

有三列擴大

data = {'function_name': ['func1', 'func2', 'func3'], 
    'argument': [('func1_arg1', 'func1_arg2'), 
       ('func2_arg1',), 
       ('func3_arg1', 'func3_arg2', 'func3_arg3')], 
    'A': ['value_a1', 'value_a2', 'value_a3'], 
    'B': 'b', 
    'types': [('func1_type1', 'func1_type2'), 
       ('func2_type1',), 
       ('func3_type1', 'func3_type2', 'func3_type3')], 
    'info': [(None, None), (None,), (None, None, None)]} 
 
    function_name   A B argument info  types 
0   func1 value_a1 b func1_arg1 None func1_type1 
1   func1 value_a1 b func1_arg2 None func1_type2 
2   func2 value_a2 b func2_arg1 None func2_type1 
3   func3 value_a3 b func3_arg1 None func3_type1 
4   func3 value_a3 b func3_arg2 None func3_type2 
5   func3 value_a3 b func3_arg3 None func3_type3 

希望它能幫助。

+1

沒錯,看起來它就像魅力!非常感謝你的幫助! – BigBear

+1

歡迎@bigbear – Dark

+0

@Parfait感謝您指出我已更新答案 – Dark

2

如果所有項目使用DataFrame構造函數的長度相等(即3),請考慮嵌套列表和dict解析。唯一的挑戰是標項目'B':'b'可在結束時,如果已知的預先分配:

dfs = [pd.DataFrame([{k:v[i] for k,v in data.items() if len(data[k])>1}][0]) \ 
      for i in range(len(data['function_name']))] 

df = pd.concat(dfs).reset_index(drop=True).assign(B='b') 

print(df) 
#   A argument function_name  types B 
# 0 value_a1 func1_arg1   func1 func1_type1 b 
# 1 value_a1 func1_arg2   func1 func1_type2 b 
# 2 value_a2 func2_arg1   func2 func2_type1 b 
# 3 value_a3 func3_arg1   func3 func3_type1 b 
# 4 value_a3 func3_arg2   func3 func3_type2 b 
# 5 value_a3 func3_arg3   func3 func3_type3 b 
+0

你可以嘗試你的解決方案,擴大三列嗎?我在解決方案中提供的數據。您的解決方案要求類型欄的長度相等。 – Dark