将包含元组列表的 Pandas 列拆分为单独的列

时间:2021-04-30 02:01:12

标签: python pandas dataframe numpy

我在 Pandas 数据框中有数据,我正在尝试从特定列 col 中分离和提取数据。 col 中的值都是各种大小的列表,用于存储 4 值元组(前 4 个键值字典)。这些值对于元组始终具有相同的相对顺序。

对于这些元组中的每一个,我希望在最终数据框中有一个单独的行,并将元组中的相应值存储在新列中。

DataFrame df 看起来像这样:

ID    col
A     [(123, 456, 111, False), (124, 456, 111, true), (125, 456, 111, False)]
B     []
C     [(123, 555, 333, True)]

我需要将 col 拆分为四列,但还要延长每条记录的数据框,以便每个元组在 df2 中都有自己的行。 DataFrame d2 应如下所示:

ID   col1  col2  col3  col4
A    123   456   111   False
A    124   456   111   True
A    125   456   111   False
B    None  None  None  None
C    123   555   333   True

我有某种基于循环的变通代码似乎可以完成工作,但我想找到一种更好、更有效的方法来运行庞大的数据集。如果可能,也许使用矢量化或 NumPy。这是我到目前为止所拥有的:

import pandas as pd

df = pd.DataFrame({'ID': ['A', 'B', 'C'], 
                   'col': [[('123', '456', '111', False),
                            ('124', '456', '111', True),
                            ('125', '456', '111', False)],
                           [],
                           [('123', '555', '333', True)]]
                   })
final_rows = []

for index, row in df.iterrows():
    if not row.col:   # if list is empty
        final_rows.append(row.ID)
    for tup in row.col:
        new_row = [row.ID]
        vals = list(tup)
        new_row.extend(vals)
        final_rows.append(new_row)

df2 = pd.DataFrame(final_rows, columns=['ID', 'col1', 'col2', 'col3', 'col4'])

2 个答案:

答案 0 :(得分:2)

这是另一种解决方案,您可以尝试使用 explode + concat

df_ = df.explode('col').reset_index(drop=True)

pd.concat(
    [df_[['ID']], pd.DataFrame(df_['col'].tolist()).add_prefix('col')], axis=1
)

  ID col0  col1  col2   col3
0  A  123   456   111  False
1  A  124   456   111   True
2  A  125   456   111  False
3  B  NaN  None  None   None
4  C  123   555   333   True

答案 1 :(得分:1)

尝试 explode 后跟 apply ( pd.Series ) 然后 merge 回到数据帧:

import pandas as pd

df = pd.DataFrame({'ID': ['A', 'B', 'C'],
                   'col': [[('123', '456', '111', False),
                            ('124', '456', '111', True),
                            ('125', '456', '111', False)],
                           [],
                           [('123', '555', '333', True)]]
                   })
# Explode into Rows
new_df = df.explode('col').reset_index(drop=True)  

# Merge Back Together
new_df = new_df.merge(
    # Turn into Multiple Columns
    new_df['col'].apply(pd.Series),
    left_index=True,
    right_index=True) \
    .drop(columns=['col'])  # Drop Old Col Column

# Rename Columns
new_df.columns = ['ID', 'col1', 'col2', 'col3', 'col4']

# For Display
print(new_df)

输出:

  ID col1 col2 col3   col4
0  A  123  456  111  False
1  A  124  456  111   True
2  A  125  456  111  False
3  B  NaN  NaN  NaN    NaN
4  C  123  555  333   True
相关问题