说我有一个包含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'
任何建议或帮助都会受到赞赏。
答案 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)
将col4
和col5
拆分为一系列列表s4
,s5
。接下来,使用np.where
将col2
与s4
和col3
与s5
和join
进行比较,以根据需要将列表字符串化
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