我有一个pandas dataframe
,其中包含split_categories列中的列表:
df.head()
album_id categories split_categories
0 66562 480.494 [480, 494]
1 114582 128 [128]
2 4846 5 [5]
3 1709 9 [9]
4 59239 105.104 [105, 104]
我想选择特定列表[480,9,104]中至少一个类别的所有行。
预期输出:
album_id categories split_categories
0 66562 480.494 [480, 494]
3 1709 9 [9]
4 59239 105.104 [105, 104]
我设法使用apply
:
def match_categories(row):
selected_categories = [480, 9, 104]
result = [int(i) for i in row['split_categories'] if i in selected_categories]
return result
df['matched_categories'] = df.apply(match_categories, axis=1)
但是此代码在生产环境中运行,并且这种方式花费的时间太长(我对包含列表的多列运行它)
有没有办法运行类似的东西:
df[~(df['split_categories'].anyvalue.isin([480, 9, 104]))]
谢谢
答案 0 :(得分:2)
您可以将每个列表转换为集合,获取交集并将其转换为bool:
L = [480, 9, 104]
mask = np.array([bool(set(map(int, x)) & set(L)) for x in df['split_categories']])
或将list column
转换为DataFrame
,强制转换为浮点并与isin
比较:
df1 = pd.DataFrame(df['split_categories'].values.tolist(), index=df.index)
mask = df1.astype(float).isin(L).any(axis=1)
df = df[mask]
print (df)
album_id categories split_categories
0 66562 480.494 [480, 494]
3 1709 9 [9]
4 59239 105.104 [105, 104]
答案 1 :(得分:2)
您可以展开内部列表,并检查内部列表中的any
项是否包含在[480, 9, 104]
中:
l = [480, 9, 104]
df[df.categories.str.split('.', expand=True).isin(map(str,l)).any(axis=1)]
album_id categories split_categories
0 66562 480.494 [480,494]
3 1709 9.000 [9]
4 59239 105.104 [105,104]
答案 2 :(得分:1)
使用:
print(df[~(df['split_categories'].isin([480, 9, 104])).any()])
输出:
album_id categories split_categories
0 66562 480.494 [480, 494]
3 1709 9 [9]
4 59239 105.104 [105, 104]
答案 3 :(得分:1)
您可以拆分为多个数字序列,然后使用矢量化布尔运算。使用逐行操作的Python级别循环通常效率更高( )。
const foo = () => {
return gulp.src("...")
.pipe(changed("..."))
.pipe(gulp.dest(function (file) {
// ...stuff
return "...";
}));
}
答案 4 :(得分:1)
另一种方法:
my_list = [480, 9, 104]
pat = r'({})'.format('|'.join(str(i) for i in my_list))
#'(480|9|104)' <-- This is how the pat looks like
df.loc[df.split_categories.astype(str).str.extract(pat, expand=False).dropna().index]
或者:
pat = '|'.join(r"\b{}\b".format(x) for x in my_list)
df[df.split_categories.astype(str).str.contains(pat,na=False)]
album_id categories split_categories
0 66562 480.494 [480, 494]
3 1709 9.000 [9]
4 59239 105.104 [105, 104]
这将与split_categories
和categories
列一起使用。