gpt4 book ai didi

python - 将列表与 DataFrame 中的每条记录进行比较

转载 作者:行者123 更新时间:2023-12-02 06:58:09 25 4
gpt4 key购买 nike

我有一个用例,我将同一列中的列表与其自身进行比较,代码如下:

for i in range(0,len(counts95)):
for j in range(i+1,len(counts95)):
for x in counts95['links'][i]:
for y in counts95['links'][j]:
if x == y and counts95['linkoflinks'][j] is None:
counts95['linkoflinks'][j] = counts95['index'][i]

该代码可以工作,但它对 Python 不友好(使用 4 个 for 循环),并且需要大量时间来执行该操作。其背后的主要思想是链接 counts95['links'] 列表中的元素位于任何后续行中的记录,如果是,则更新列 linksoflinks :仅当 linksoflinks 列为 None(不覆盖)时才显示第一列的索引

找到下面的引用表:

counts95 = pd.DataFrame({'index': [616351, 616352, 616353,6457754], 
'level0': [25,30,35,100],
'links' : [[1,2,3,4,5],[23,45,2],[1,19,67],[14,15,16]],
'linksoflinks' : [None,None,None,None]})

编辑:新数据框

counts95 = pd.DataFrame({'index': [616351, 616352, 616353,6457754,6566666,464664683], 
'level0': [25,30,35,100,200,556],
'links' : [[1,2,3,4,5],[23,45,2],[1,19,67],[14,15,16],[1,14],[14,1]],
'linksoflinks' : [None,None,None,None,None,None]})

期望的输出:

     index  level0            links  linksoflinks
0 616351 25 [1, 2, 3, 4, 5] NaN
1 616352 30 [23, 45, 2] 616351.0
2 616353 35 [1, 19, 67] 616351.0
3 6457754 100 [14, 15, 16] NaN
4 6566666 200 [1,14] 616351.0
5 6457754 556 [14,1] 616351.0

最佳答案

与示例数据帧构造函数相比,您所需的输出使用不同的值和列名称。我使用您想要的输出数据帧进行测试。

逻辑:
对于links的每个子列表,我们需要找到第一个重叠子列表的行索引(我的意思是数据帧的索引,而不是列index)。我们将使用这些行索引在 counts95 上按 .loc 进行切片,以获得列 index 的相应值。为了实现这一目标,我们需要执行以下几个步骤:

  • 将每个子列表与link 中的所有子列表进行比较。列表理解是快速高效地完成这项任务。我们需要编写一个列表理解创建 bool 二维掩码数组,其中每个子数组包含重叠行的 True 值和非重叠行的 False 值(请查看此步骤2D 掩模并检查链接列,您会看得更清楚)
  • 我们想要从顶部到当前子列表进行比较。 IE。常设从当前行开始,我们只想向后比较到顶部。因此,我们需要将任何前向比较设置为False。这是np.tril
  • 的功能
  • 在此 2D 掩码的每个子数组内,True 的位置/索引为当前子列表重叠的行的行索引。我们需要找到这些位置为True。这是np.argmax的功能。np.argmax 返回数组第一个最大元素的位置/索引。 True 被视为 1False 被视为 0。所以,在任何具有 True 的子数组上,它会正确返回第一个重叠行索引。但是,在所有 False 子数组上,它返回 0。稍后我们将使用 where
  • 处理所有 False 子数组
  • np.argmax之后,2D-mask 被缩减为 1D-mask。的每个元素该一维掩码是重叠子列表的行索引数。将其传递给.loc以获取index列的相应值。但是,结果也错误地包含了 row where 的子数组2D-mask 包含所有False。我们希望这些行变成 NaN。这是.where 的功能

方法一:
使用列表理解在每个 links 列表与 links 中的所有列表之间构造 bool 2D 掩码 m。我们只需要向后比较,因此使用np.tril将掩码的右上角三角形压缩为所有代表向前比较的False。最后,调用 np.argmax 获取 m 每行中第一个 True 的位置,并链接要转动的 where m 的所有 False 行变为 NaN

c95_list = counts95.links.tolist()
m = np.tril([[any(x in l2 for x in l1) for l2 in c95_list] for l1 in c95_list],-1)
counts95['linkoflist'] = (counts95.loc[np.argmax(m, axis=1), 'index']
.where(m.any(1)).to_numpy())

Out[351]:
index level0 links linkoflist
0 616351 25 [1, 2, 3, 4, 5] NaN
1 616352 30 [23, 45, 2] 616351.0
2 616353 35 [1, 19, 67] 616351.0
3 6457754 100 [14, 15, 16] NaN
4 6566666 200 [1, 14] 616351.0
5 6457754 556 [14, 1] 616351.0
<小时/>

方法2:
如果数据帧很大,则将每个子列表仅与链接的顶部部分进行比较会使速度更快。在大数据帧上,方法 1 的速度可能是方法 1 的两倍。

c95_list = counts95.links.tolist()
m = [[any(x in l2 for x in l1) for l2 in c95_list[:i]] for i,l1 in enumerate(c95_list)]
counts95['linkoflist'] = counts95.reindex([np.argmax(y) if any(y) else np.nan
for y in m])['index'].to_numpy()
<小时/>

分步说明(方法1)

m = np.tril([[any(x in l2 for x in l1) for l2 in c95_list] for l1 in c95_list],-1)

Out[353]:
array([[False, False, False, False, False, False],
[ True, False, False, False, False, False],
[ True, False, False, False, False, False],
[False, False, False, False, False, False],
[ True, False, True, True, False, False],
[ True, False, True, True, True, False]])

argmax 返回所有 False 行中第一个 True 和第一个 False 的位置。

In [354]: np.argmax(m, axis=1)
Out[354]: array([0, 0, 0, 0, 0, 0], dtype=int64)

使用argmax的结果进行切片

counts95.loc[np.argmax(m, axis=1), 'index']

Out[355]:
0 616351
0 616351
0 616351
0 616351
0 616351
0 616351
Name: index, dtype: int64

链接 where 将所有 False 对应的行从 m 转换为 NaN

counts95.loc[np.argmax(m, axis=1), 'index'].where(m.any(1))

Out[356]:
0 NaN
0 616351.0
0 616351.0
0 NaN
0 616351.0
0 616351.0
Name: index, dtype: float64

最后,输出的索引与 counts95 的索引不同,因此只需调用 to_numpy 即可获取 ndarray 分配给列 linkoflist counts95

关于python - 将列表与 DataFrame 中的每条记录进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60496917/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com