布尔值屏蔽每一行中不同长度的列表
Boolean masking a list of different lengths within each individual row
我有以下数据框:
df = pd.DataFrame({
'tags': [
[{'id': 1401}, {'id': 1801}],
[{'id': 502}, {'id': 703}, {'id': 1801}],
[{'id': 1801}]
]
})
我只对 'tags'
列中的 'id': 1801
值感兴趣,如果 'id': 1801
存在或 False
如果不是。
如有任何帮助,我们将不胜感激
如果性能对 get
很重要,则使用带有 any
的 lambda 函数进行测试,如果缺少 id
:
df = pd.DataFrame({
'tags': [
[{'id': 1401}, {'id': 1801}],
[{'id': 502}, {'id': 703}, {'id': 1801}],
[{'id': 1}]
]
})
df['new'] = df['tags'].apply(lambda x: any(y.get('id') == 1801 for y in x))
print (df)
tags new
0 [{'id': 1401}, {'id': 1801}] True
1 [{'id': 502}, {'id': 703}, {'id': 1801}] True
2 [{'id': 1}] False
df = pd.concat([df] * 1000, ignore_index=True)
In [275]: %timeit df['tags'].explode().str['id'].eq(1801).any(level=0)
8.09 ms ± 265 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [276]: %timeit df['tags'].apply(lambda x: any(y.get('id') == 1801 for y in x))
2.64 ms ± 6.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
如果总是 id
每个 tags
存在:
In [283]: %timeit [any(d['id'] == 1801 for d in l) for l in df['tags']]
2.44 ms ± 215 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
我们可以 explode
tags
列然后使用 str
访问器获取 id
的值并将其与 1801
进行比较以创建布尔掩码接着 any
在 level=0
上减少:
df['flag'] = df['tags'].explode().str['id'].eq(1801).any(level=0)
如果数据帧很大并且需要考虑性能,那么我们可以使用 list comprehension
,它将胜过所有可用的基于 pandas 的解决方案
df['flags'] = [any(d['id'] == 1801 for d in l) for l in df['tags']]
tags flag
0 [{'id': 1401}, {'id': 1801}] True
1 [{'id': 502}, {'id': 703}, {'id': 1801}] True
2 [{'id': 1801}] True
我有以下数据框:
df = pd.DataFrame({
'tags': [
[{'id': 1401}, {'id': 1801}],
[{'id': 502}, {'id': 703}, {'id': 1801}],
[{'id': 1801}]
]
})
我只对 'tags'
列中的 'id': 1801
值感兴趣,如果 'id': 1801
存在或 False
如果不是。
如有任何帮助,我们将不胜感激
如果性能对 get
很重要,则使用带有 any
的 lambda 函数进行测试,如果缺少 id
:
df = pd.DataFrame({
'tags': [
[{'id': 1401}, {'id': 1801}],
[{'id': 502}, {'id': 703}, {'id': 1801}],
[{'id': 1}]
]
})
df['new'] = df['tags'].apply(lambda x: any(y.get('id') == 1801 for y in x))
print (df)
tags new
0 [{'id': 1401}, {'id': 1801}] True
1 [{'id': 502}, {'id': 703}, {'id': 1801}] True
2 [{'id': 1}] False
df = pd.concat([df] * 1000, ignore_index=True)
In [275]: %timeit df['tags'].explode().str['id'].eq(1801).any(level=0)
8.09 ms ± 265 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [276]: %timeit df['tags'].apply(lambda x: any(y.get('id') == 1801 for y in x))
2.64 ms ± 6.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
如果总是 id
每个 tags
存在:
In [283]: %timeit [any(d['id'] == 1801 for d in l) for l in df['tags']]
2.44 ms ± 215 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
我们可以 explode
tags
列然后使用 str
访问器获取 id
的值并将其与 1801
进行比较以创建布尔掩码接着 any
在 level=0
上减少:
df['flag'] = df['tags'].explode().str['id'].eq(1801).any(level=0)
如果数据帧很大并且需要考虑性能,那么我们可以使用 list comprehension
,它将胜过所有可用的基于 pandas 的解决方案
df['flags'] = [any(d['id'] == 1801 for d in l) for l in df['tags']]
tags flag
0 [{'id': 1401}, {'id': 1801}] True
1 [{'id': 502}, {'id': 703}, {'id': 1801}] True
2 [{'id': 1801}] True