有条件地从数据框的列中的逗号分隔值中删除项目

时间:2019-09-23 09:37:05

标签: python pandas list lambda

说我有一个包含4列的数据框,其中两列是项目的逗号分隔值,其他两列只是值。

    df.head()
    col1 col2 col3  col4     col5
    a.    34  67 34,44,55  41,54,67
    b.    75   105  75,90   85 105

如果与col4中的值相等,我需要从col2中删除第一项。因此,我想删除col5中的最后一项,如果它等于col3

最后,数据框应如下所示:

 df2.head()

    col1 col2 col3  col4     col5
    a.    34   67   44,55  41,54
    b.    75   105   90   85

我尝试使用:

df.col4.map(lambda x: x.pop(0))
AttributeError: 'str' object has no attribute 'pop'

任何建议或帮助都会受到赞赏。

4 个答案:

答案 0 :(得分:1)

好像col4值实际上不是strs列表-您应该在这些字符串上使用split(',')(并可能在编辑后将其强制返回str,这取决于您以后打算做什么)。另外,pop()将返回该元素,因此也许切片会更好:lambda x: x.split(',')[1:]

答案 1 :(得分:1)

假设您的数据帧定义为:

df = pd.DataFrame(data=[[34, 67, "34,44,55", "41,54,67"], [75, 105, "75,90", "85,105"]], columns=["col2","col3","col4","col5"])

您将获得以下数据框:

   col2 col3  col4      col5
0   34  67    34,44,55  41,54,67
1   75  105   75,90     85,105

您可以将.apply()axis=1结合使用,以在每个数据框行上应用函数。

在此函数中,首先通过分割col4 (or col5),中的字符串转换为列表。然后,您可以循环浏览列表中的项目,并仅保留不等于col2 (or col3)中整数的项目。

df["col4"] = df.apply(lambda row: ",".join([item for item in row["col4"].split(",") if int(item) != row["col2"]]), axis=1)
df["col5"] = df.apply(lambda row: ",".join([item for item in row["col5"].split(",") if int(item) != row["col3"]]), axis=1)

这是您将获得的输出:

    col2    col3    col4    col5
0   34      67      44,55   41,54
1   75      105     90      85

答案 2 :(得分:1)

显然您有一些间距不一致的问题,您可能需要修复它。但这考虑了您的需要:

df['col4'] = df.apply(lambda row: row['col4'] if row['col4'].split(',')[0].strip() != str(row['col2']) else ','.join(row['col4'].split(',')[1:]), axis=1)
df['col5'] = df.apply(lambda row: row['col5'] if row['col5'].split(',')[-1].strip() != str(row['col3']) else ','.join(row['col5'].split(',')[:-1]), axis=1)

答案 3 :(得分:1)

col4col5拆分为一系列列表s4s5。接下来,使用np.wherecol2s4col3s5join进行比较,以根据需要将列表字符串化

s4 = df.col4.str.split(',\s*|\s+')
s5 = df.col5.str.split(',\s*|\s+') 
df['new_col4'] = np.where(df.col2.eq(s4.str[0].astype(int)), s4.str[1:].str.join(','), df.col2)
df['new_col5'] = np.where(df.col3.eq(s5.str[-1].astype(int)), s5.str[:-1].str.join(','), df.col3)

Out[358]:
  col1  col2  col3      col4      col5 new_col4 new_col5
0   a.    34    67  34,44,55  41,54,67    44,55    41,54
1   b.    75   105    75,90     85 105       90       85