Python:如何在没有循环的数据框中查找值?

Posted

技术标签:

【中文标题】Python:如何在没有循环的数据框中查找值?【英文标题】:Python: how to find values in a dataframe without loop? 【发布时间】:2017-04-24 04:28:31 【问题描述】:

我有两个数据框 netM

net =
        i  j   d
    0   5  3   3 
    1   2  0   2
    2   3  2   1 
    3   4  5   2   
    4   0  1   3
    5   0  3   4


M =
    0    1    2    3    4    5
0   0    3    2    4    1    5 
1   3    0    2    0    3    3 
2   2    2    0    1    1    4 
3   4    0    1    0    3    3     
4   1    3    1    3    0    2
5   5    3    4    3    2    0

我想在M 中找到与net['d'] 相同的值,在M 中随机选择一个单元格并创建一个包含该单元格坐标的新数据框。比如

net['d'][0] = 3  

所以在M我找到了:

M[0][1]
M[1][0]
M[1][4]
M[1][5]
...

最后net1 会是这样的

   net1 =
       i1  j1   d1
    0   1   5    3 
    1   5   4    2
    2   2   3    1 
    3   1   2    2   
    4   1   5    3
    5   3   0    4

这就是我正在做的事情:

I1 = []
J1 = []
for i in net.index:
    tmp = net['d'][i]
    ds = np.where( M == tmp)
    size = len(ds[0])
    ind = randint(size) ## find two random locations with distance ds
    h = ds[0][ind]
    w = ds[1][ind]
    I1.append(h)
    J1.append(w)
net1 = pd.DataFrame()
net1['i1'] = I1
net1['j1'] = J1
net1['d1'] = net['d']

我想知道哪个是避免该循环的最佳方法

【问题讨论】:

【参考方案1】:

您可以将 M 的列堆叠起来,然后用替换对其进行采样

net = pd.DataFrame('i':[5,2,3,4,0,0], 
                    'j':[3,0,2,5,1,3], 
                    'd':[3,2,1,2,3,4])

M = pd.DataFrame(0:[0,3,2,4,1,5], 
                  1:[3,0,2,0,3,3], 
                  2:[2,2,0,1,1,4],
                  3:[4,0,1,0,3,3],
                  4:[1,3,1,3,0,2],
                  5:[5,3,4,3,2,0])

def random_net(net, M):
    # make long table and randomize order of rows and rename columns
    net1 = M.stack().reset_index()
    net1.columns =['i1', 'j1', 'd1']

    # get size of each group for random mapping
    net1_id_length = net1.groupby('d1').size()

    # add id column to uniquely identify row in net
    net_copy = net.copy()

    # first map gets size of each group and second gets random integer
    net_copy['id'] = net_copy['d'].map(net1_id_length).map(np.random.randint)
    net1['id'] = net1.groupby('d1').cumcount()

    # make for easy lookup
    net_copy = net_copy.set_index(['d', 'id'])
    net1 = net1.set_index(['d1', 'id'])

    # choose from net1 only those from original net
    return net1.reindex(net_copy.index).reset_index('d').reset_index(drop=True).rename(columns='d':'d1')

random_net(net, M)

输出

   d1  i1  j1
0   3   5   1
1   2   0   2
2   1   3   2
3   2   1   2
4   3   3   5
5   4   0   3

600 万行的计时

n = 1000000
net = pd.DataFrame('i':[5,2,3,4,0,0] * n, 
                    'j':[3,0,2,5,1,3] * n, 
                    'd':[3,2,1,2,3,4] * n)

M = pd.DataFrame(0:[0,3,2,4,1,5], 
                  1:[3,0,2,0,3,3], 
                  2:[2,2,0,1,1,4],
                  3:[4,0,1,0,3,3],
                  4:[1,3,1,3,0,2],
                  5:[5,3,4,3,2,0])

%timeit random_net(net, M)

1 次循环,3 次取胜:每个循环 13.7 秒

【讨论】:

但我只想以相同的顺序获取net['d'] 的值,以便net['d'] = net['d1'] 现在检查函数。它将以相同的顺序为您提供与原始尺寸相同的随机新网。它实际上仍然不完全正确 - 等等.... 太完美了! 好的,现在很好用。它现在从原始网络交叉连接到由堆叠表 M 形成的网络。然后它为 net['d'] 中的每个原始值随机选择 1 个新的 i1,j1 组合。在 net['d'] 中有重复项时只选择错误的值之前 我在尝试合并数据框时收到错误消息。 nets_merged = temp_net.merge(net1, left_on='d', right_on='d1')我得到MemoryError:

以上是关于Python:如何在没有循环的数据框中查找值?的主要内容,如果未能解决你的问题,请参考以下文章

在 Pandas 数据框中查找唯一值,无论行或列位置如何

如何使用熊猫从另一个数据框中的一个数据框中查找值?

python如何检查数据框中的值是不是为nan [重复]

如何使用 loc[i,j] 根据索引值访问数据框中的特定值

Python:如何从具有多列的数据框中循环遍历每两列组合以进行聚类?

如何在包含子字符串的数据框中查找所有行?