【问题标题】:Pandas Dataframe - Values are listsPandas Dataframe - 值是列表
【发布时间】:2022-01-09 03:47:50
【问题描述】:

我有一个只有一列的 Pandas 数据框,但每一行的值是五个元素的列表,如下所示:

Column
timestamp
06:54:00 [1, 2, 3, 4, 5 ]
06:55:00 [0.5, 2.3, 4.5, 1, 3 ]

我想分离数据,以便获得另外五列,每列包含每行列表的一个值。像这样(我只放了前两个以节省空间):

Column Column 1 Column 2
timestamp
06:54:00 [1, 2, 3, 4, 5 ] 1 2
06:55:00 [0.5, 2.3, 4.5, 1, 3 ] 0.5 2.3

我试过了:

        L = [pd.DataFrame(data[col].values.tolist()) for col in data]
        print(L)
        df_new = pd.concat(L, axis=1, ignore_index=True)
        print(df_new)

        for column in data.columns:
            column_name = f'TColumn {column}'
            val = data[column][column]
            n = 0
            for n in range(5):
                data[column_name] = val[n]
                n = n + 1
        print(data)

我没有得到任何东西,有人可以帮我解决这个问题吗?

提前谢谢你,

【问题讨论】:

    标签: python list dataframe


    【解决方案1】:

    您必须先创建列,然后将df['Column'].values 转换为列表并将其分配给新创建的列。你可以这样做:

    for i in range(1,6):
        df['Column '+str(i)] = np.nan
    df.loc[:,'Column 1':'Column 5'] = df['Column'].tolist()
    

    【讨论】:

    • 您好,我认为您实际上不需要在分配值之前创建列,因为 pandas DataFrame 可以为我们做到这一点
    【解决方案2】:

    为了进一步简化@Manlai A 发布的内容,我们可以像这样即时创建新列:

    df[[f'Column {i}' for i in range(5)]] = df['Columns'].tolist()
    

    是的,这个 oneliner 实际上回答了上面的问题。

    这里有一个带有虚拟数据的小演示,以帮助它更可重复: https://colab.research.google.com/drive/1NJLuS0thpjz4U-REpu1vOtrSfYdWmFIn?usp=sharing

    编辑 1

    对于下面评论部分提出的第二个问题:

    “如果我现在有一些具有空列表的行是值 ([]),其余的与示例中的一样(具有 5 或 6 个元素的列表),我想创建一个新列,其中第一个列表的元素,如果为空,只需删除该行,我该怎么做?”

    例如,如果您有一个像这样的虚拟表df

        Columns
    0   []
    1   [2]
    2   [18, 14]
    3   [12, 19, 5]
    4   [13, 12, 2, 19]
    5   [8, 0, 10, 19, 8]
    6   [12, 1, 4, 7, 14, 14]
    7   [18, 2, 6, 12, 6, 12, 9]
    8   [0, 8, 4, 19, 4, 5, 7, 4]
    9   [11, 8, 5, 11, 3, 2, 4, 6, 12]
    

    如果你想获取每行的第一项,你可以这样做:

    df['Item'] = df['Columns'].apply(lambda items: items[0] if len(items) else None)
    

    表格会变成:

        Columns                          Item
    0   []                                NaN
    1   [2]                               2.0
    2   [18, 14]                         18.0
    3   [12, 19, 5]                      12.0
    4   [13, 12, 2, 19]                  13.0
    5   [8, 0, 10, 19, 8]                 8.0
    6   [12, 1, 4, 7, 14, 14]            12.0
    7   [18, 2, 6, 12, 6, 12, 9]         18.0
    8   [0, 8, 4, 19, 4, 5, 7, 4]         0.0
    9   [11, 8, 5, 11, 3, 2, 4, 6, 12]   11.0
    

    之后,您可以简单地删除任何包含 NA 值(Nonenp.NaNpd.NA 等)的行:

    df = df.dropna(axis=0)
    

    它会变成:

        Columns                          Item
    1   [2]                               2.0
    2   [18, 14]                         18.0
    3   [12, 19, 5]                      12.0
    4   [13, 12, 2, 19]                  13.0
    5   [8, 0, 10, 19, 8]                 8.0
    6   [12, 1, 4, 7, 14, 14]            12.0
    7   [18, 2, 6, 12, 6, 12, 9]         18.0
    8   [0, 8, 4, 19, 4, 5, 7, 4]         0.0
    9   [11, 8, 5, 11, 3, 2, 4, 6, 12]   11.0
    

    请注意,索引 0 现在已丢失。要重置索引,您可以调用

    df = df.reset_index()
    

    我还将第二个答案包含在之前的 demo 中。

    【讨论】:

    • 我首先想到了这个解决方案,但这给了我一个关键错误。
    • 啊,好吧。然后我将提供一个小演示。我认为它会更有用和可重复@ManlaiA。谢谢
    • 我看到这在您的演示中有效,但由于某种原因,在我的代码中尝试运行它时出现错误:ValueError: setting an array element with a sequence. TypeError: only size-1 arrays can be converted to Python scalars
    • 对不起,我终于成功了!您的代码是正确的,问题是我的列表中有 6 个(我没有看到其中一个)而不是 5 个元素,所以我更改了范围,现在它工作得很好。谢谢!
    • @yaputrajordi 效果很好,非常感谢!! :)
    猜你喜欢
    • 1970-01-01
    • 2018-05-10
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 1970-01-01
    • 2018-09-16
    相关资源
    最近更新 更多