簡體   English   中英

將 function 應用於 ndarray 的行 && 將 itertool object 轉換為 numpy 數組

[英]applying a function to rows of a ndarray && converting itertool object to numpy array

我正在嘗試從一組實數創建大小為 4 的排列。 之后,我想知道排序后排列中第一個元素的 position。 到目前為止,這是我嘗試過的。 最好的方法是什么?

import numpy as np
from itertools import chain, permutations

N_PLAYERS = 4
N_STATES = 60
np.random.seed(0)
state_space = np.linspace(0.0, 1.0, num=N_STATES, retstep=True)[0].tolist()
perms = permutations(state_space, N_PLAYERS)
perms_arr = np.fromiter(chain(*perms),dtype=np.float16)
def loc(row):
  return np.where(np.argsort(row) == 0)[0].tolist()[0]
locs = np.apply_along_axis(loc, 0, perms)
In [153]: N_PLAYERS = 4
     ...: N_STATES = 60
     ...: np.random.seed(0)
     ...: state_space = np.linspace(0.0, 1.0, num=N_STATES, retstep=True)[0].tolist()
     ...: perms = itertools.permutations(state_space, N_PLAYERS)
In [154]: alist = list(perms)
In [155]: len(alist)
Out[155]: 11703240

簡單地從排列中制作一個列表會產生一個列表列表,其中所有子列表的長度為N_PLAYERS

用 chain 制作一個數組使其變平:

In [156]: perms = itertools.permutations(state_space, N_PLAYERS)
In [158]: perms_arr = np.fromiter(itertools.chain(*perms),dtype=np.float16)
In [159]: perms_arr.shape
Out[159]: (46812960,)
In [160]: alist[0]

可以將其重塑為 (11703240,4)。

在該 1d 數組上使用apply不起作用(或有意義):

In [170]: perms_arr.shape
Out[170]: (46812960,)
In [171]: locs = np.apply_along_axis(loc, 0, perms_arr)
In [172]: locs.shape
Out[172]: ()

重塑為 4 列:

In [173]: locs = np.apply_along_axis(loc, 0, perms_arr.reshape(-1,4))
In [174]: locs.shape
Out[174]: (4,)
In [175]: locs
Out[175]: array([     0, 195054, 578037, 769366])

這將loc應用於每一列,為每一列返回一個值。 但是loc有一個row變量。 那應該很重要嗎?

我可以切換軸; 這需要更長的時間,而且

In [176]: locs = np.apply_along_axis(loc, 1, perms_arr.reshape(-1,4))
In [177]: locs.shape
Out[177]: (11703240,)

列表理解

這個迭代與你的apply_along_axis做同樣的事情,我希望它更快(雖然我沒有計時 - 它太慢了)。

In [188]: locs1 = np.array([loc(row) for row in perms_arr.reshape(-1,4)])
In [189]: np.allclose(locs, locs1)
Out[189]: True

全數組排序

但是argsort采用一個軸,所以我可以一次對所有行進行排序(而不是迭代):

In [185]: np.nonzero(np.argsort(perms_arr.reshape(-1,4), axis=1)==0)
Out[185]: 
(array([       0,        1,        2, ..., 11703237, 11703238, 11703239]),
 array([0, 0, 0, ..., 3, 3, 3]))
In [186]: np.allclose(_[1],locs)
Out[186]: True

或者轉向另一個方向:- cf with Out[175]

In [187]: np.nonzero(np.argsort(perms_arr.reshape(-1,4), axis=0)==0)
Out[187]: (array([     0, 195054, 578037, 769366]), array([0, 1, 2, 3]))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM