我有一个包含大约90k字符串的列表,以及一个包含多列的数据框,我有兴趣检查列表中的字符串是否在column_1中,以及是否在column_2处分配了相同的值。
我可以这样做:
for i in range(len(my_list)):
item = list[i]
for j in range(len(df)):
if item == df['column_1'][j]:
df['column_2'][j] = item
但我宁愿避免使用嵌套循环
我试过这个
for item in my list:
if item in list(df['column _1']):
position = df[df['column_1']==item]].index.values[0]
df['column_2'][position] = item
但我认为这个解决方案更慢,更难阅读,这个操作可以通过简单的列表理解来完成吗?
编辑。
第二种解决方案相当快,大约一个数量级。 这是为什么?似乎在那种情况下它必须搜索两次马赫:
这里:
if item in list(df['column _1'])
在这里:
possition = df[df['column_1]=='tem]].index.values[0]
我仍然希望有一个更简单的解决方案。
答案 0 :(得分:3)
您可以通过将您描述的过滤和分配操作分为两个不同的步骤来完成此操作。
Pandas系列对象包含一个'isin'方法,可以让您识别其column_1值在my_list中的行,并将结果保存在布尔值系列中。这可以与.loc索引方法一起使用,将值从第1列的相应行复制到第2列
# Identify the matching rows
matches = df['column_1'].isin(my_list)
# Set the column_2 entries to column_1 in the matching rows
df.loc[matches,'column_2'] = df.loc[matches,'column_1']
如果column_2尚不存在,则此方法会创建column_2并将non_matching值设置为NaN。 .loc方法用于在执行索引操作时避免对数据副本进行操作。
答案 1 :(得分:2)
假设你有一个清单:
l = ['foo', 'bar']
和一个DataFrame:
df = pd.DataFrame(['some', 'short', 'string', 'has', 'foo'], columns=['col1'])
您可以使用df.apply
df['col2'] = df.apply(lambda x: x['col1'] if x['col1'] in l else None, axis=1)
df
col1 col2
0 some None
1 short None
2 string None
3 has None
4 foo foo
答案 2 :(得分:1)
根据传统观点,你不应该使用列表理解副作用。你将创建一个你不需要的(可能是巨大的)列表,浪费资源并损害可读性。
https://codereview.stackexchange.com/questions/58050/is-it-pythonic-to-create-side-effect-inside-list-comprehension Is it Pythonic to use list comprehensions for just side effects? Python loops vs comprehension lists vs map for side effects (i.e. not using return values)
答案 3 :(得分:1)
试试这个单行:
df.loc[(df['column_1'].isin(my_list)), 'column_2'] = df['column_1']
@ res_edit解决方案的不同之处在于缺少第二个df.loc[]
,它应该更快一点......