【问题标题】:Iterating over lists in pandas dataframe to remove everything after certain value in list迭代熊猫数据框中的列表以删除列表中特定值后的所有内容
【发布时间】:2021-11-11 16:59:34
【问题描述】:

我想根据列事件中“1”的出现来过滤我的数据框值。 当出现 1 时,应删除 1 之后的所有内容。

当我有一个单一列表时,这有效:

event = [5, 5, 5, 5, 1, 5]
index = event.index(1)
event[:index]

输出:

[5, 5, 5, 5]

现在我想为我的整个数据框执行此操作,如下所示:

| session_id | events |
|00000000000 | [4,5,5,3,2,1,5] |
|00000000001 | [4,5,5,1,2,1,5,5,5] |
|00000000002 | [4,5,1,3,2,1,5,5,5,1] |
import pandas as pd

df = pd.DataFrame([['00000000000 ', [4, 5, 5, 3, 2, 1, 5]],
                   ['00000000001', [4, 5, 5, 1, 2, 1, 5, 5, 5]],
                   ['00000000002 ', [4, 5, 1, 3, 2, 1, 5, 5, 5, 1]]],
                  columns=['session_id', 'events'])

但我似乎无法做到正确。有人可以帮助我吗? 我的最终解决方案是这样做:

for i, row in df.iterrows():
    target_id = row['events'].index(1)
    df['events_short'] = row['events'][:target_id]

但它给了我以下错误:

ValueError: Length of values (4) does not match length of index (10)

【问题讨论】:

    标签: python pandas list


    【解决方案1】:

    修复

    你的df['events_short'] = 表示设置一个新的整列,这不是你想要的,你只需要设置一个单元格

    df['events_short'] = ""
    for i, row in df.iterrows():
        df.at[i, 'events_short'] = row['events'][:row['events'].index(1)]
    

    或覆盖

    for i, row in df.iterrows():
        df.at[i, 'events'] = row['events'][:row['events'].index(1)]
    

    改进

    您还可以使用Series.apply 将您的逻辑应用于列的每个单元格

    df['events'] = df['events'].apply(lambda x: x[:x.index(1)])
    

    【讨论】:

    • 非常感谢!两种解决方案都有效。我只剩下一个问题,我还没有想到。在某些行中,1 不会出现。发生这种情况时该怎么办,因为现在我会收到错误消息。
    猜你喜欢
    • 1970-01-01
    • 2018-12-18
    • 2020-07-30
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多