Pandas group_by 字符串列,其值包含在单独的列表中
Pandas group_by string column which values contained in a separate list
我有一个基于层次结构的事件流,其中每个层次结构父节点(表示为 level0/1)有多个子节点(level0(0/1/2) 和子子节点(level00(0/1/ 2)). "level"只是一个占位符,每个层级都有自己唯一的名称。唯一的规则是父节点层级字符串总是包含在子节点层级字符串名称中。假设这个事件流有300k和更多条目。
| index | hierarchystr |
| ----- | --------------------- |
| 0 | level0level00level000|
| 1 | level0level01 |
| 2 | level0level02level021|
| 3 | level0level02level021|
| 4 | level0level02level020|
| 5 | level0level02level021|
| 6 | level1level02level021|
| 7 | level1level02level021|
| 8 | level1level02level021|
| 9 | level2level02level021|
现在我想通过一个单独的列表做一个包容性的 group_by 如果数组中的字符串包含在 hierarchystr 列的字符串中,则应该包含该行,预期输出(注意 hstrs 是每个时间顺序不同!):
#hstrs = ["level0", "level1", "level0level01", "level0level02", "level0level02level021"]
|index| 0 | Count |
|-----|---------------------|-------|
|0 |level0 | 6 |
|1 |level1 | 3 |
|2 |level0level01 | 1 |
|3 |level0level02 | 4 |
|4 |level0level02level021| 3 |
我尝试了以下解决方案,但都非常慢:
#V1
for hstr in hstrs:
s = df[df.hierarchystr.str.contains(hstr)]
s2 = s.count()
s3 = s2.values[0]
if s3 > 200:
beforeset.append(hstr)
#V2
for hstr in hstrs:
s = df.hierarchystr.str.extract('(' + hstr + ')', expand=True)
s2 = s.count()
s3 = s2.values[0]
if s3 > 200:
list.append(hstr)
#V3 - fastest, but also slow and not satisfying
containing =[item for hierarchystr in df.hierarchystr for item in hstrs if item in hierarchystr]
containing = Counter(containing)
df1 = pd.DataFrame([containing]).T
nodeNamesWithOver200 = df1[df1 > 200].dropna().index.values
我也用 pat 和 extract 一次尝试了所有变量的版本,但在 return 中每组的大小在每个 运行 中变化,因为列表 hstrs 是每个 运行顺序不同。
df.hierarchystr.extract[all](pat="|".join(hstrs))
是否有可能的正则表达式和方法一步完成此任务,因此这也适用于在适当时间的大型数据帧 - 这不取决于 hstrs 数组的顺序?
你可以试试:
count = [df['hierarchystr'].str.startswith(hstr).sum() for hstr in hstrs]
out = pd.DataFrame({'hstr': hstrs, 'count': count})
print(out)
# Output
hstr count
0 level0 6
1 level1 3
2 level0level01 1
3 level0level02 4
4 level0level02level021 3
我有一个基于层次结构的事件流,其中每个层次结构父节点(表示为 level0/1)有多个子节点(level0(0/1/2) 和子子节点(level00(0/1/ 2)). "level"只是一个占位符,每个层级都有自己唯一的名称。唯一的规则是父节点层级字符串总是包含在子节点层级字符串名称中。假设这个事件流有300k和更多条目。
| index | hierarchystr |
| ----- | --------------------- |
| 0 | level0level00level000|
| 1 | level0level01 |
| 2 | level0level02level021|
| 3 | level0level02level021|
| 4 | level0level02level020|
| 5 | level0level02level021|
| 6 | level1level02level021|
| 7 | level1level02level021|
| 8 | level1level02level021|
| 9 | level2level02level021|
现在我想通过一个单独的列表做一个包容性的 group_by 如果数组中的字符串包含在 hierarchystr 列的字符串中,则应该包含该行,预期输出(注意 hstrs 是每个时间顺序不同!):
#hstrs = ["level0", "level1", "level0level01", "level0level02", "level0level02level021"]
|index| 0 | Count |
|-----|---------------------|-------|
|0 |level0 | 6 |
|1 |level1 | 3 |
|2 |level0level01 | 1 |
|3 |level0level02 | 4 |
|4 |level0level02level021| 3 |
我尝试了以下解决方案,但都非常慢:
#V1
for hstr in hstrs:
s = df[df.hierarchystr.str.contains(hstr)]
s2 = s.count()
s3 = s2.values[0]
if s3 > 200:
beforeset.append(hstr)
#V2
for hstr in hstrs:
s = df.hierarchystr.str.extract('(' + hstr + ')', expand=True)
s2 = s.count()
s3 = s2.values[0]
if s3 > 200:
list.append(hstr)
#V3 - fastest, but also slow and not satisfying
containing =[item for hierarchystr in df.hierarchystr for item in hstrs if item in hierarchystr]
containing = Counter(containing)
df1 = pd.DataFrame([containing]).T
nodeNamesWithOver200 = df1[df1 > 200].dropna().index.values
我也用 pat 和 extract 一次尝试了所有变量的版本,但在 return 中每组的大小在每个 运行 中变化,因为列表 hstrs 是每个 运行顺序不同。
df.hierarchystr.extract[all](pat="|".join(hstrs))
是否有可能的正则表达式和方法一步完成此任务,因此这也适用于在适当时间的大型数据帧 - 这不取决于 hstrs 数组的顺序?
你可以试试:
count = [df['hierarchystr'].str.startswith(hstr).sum() for hstr in hstrs]
out = pd.DataFrame({'hstr': hstrs, 'count': count})
print(out)
# Output
hstr count
0 level0 6
1 level1 3
2 level0level01 1
3 level0level02 4
4 level0level02level021 3