我目前正在嘗試對陣列進行洗牌,但遇到了一些問題。
我擁有的:
my_array=array([nan, 1, 1, nan, nan, 2, nan, ..., nan, nan, nan])
我想要做什么:
我想在將數字(例如1,1陣列中的)保持在一起的同時對資料集進行混洗。我所做的是首先將每個nan轉換為唯一的負數。
my_array=array([-1, 1, 1, -2, -3, 2, -4, ..., -2158, -2159, -2160])
之后我把所有東西都用熊貓分開了:
df = pd.DataFrame(my_array)
df.rename(columns={0: 'sampleID'}, inplace=True)
groups = [df.iloc[:, 0] for _, df in df.groupby('sampleID')]
如果我知道 shuffle 我的資料集,我將有相同的概率讓每個組出現在給定的位置,但這會忽略每個組中的元素數量。如果我有一組像[9,9,9,9,9,9]它這樣的幾個元素,它應該比一些 random 更早出現nan。如果我錯了,請糾正我。
解決這個問題的一種方法是 numpys 選擇方法。為此,我必須創建一個概率陣列
probability_array = np.zeros(len(groups))
for index, item in enumerate(groups):
probability_array[index] = len(item) / len(groups)
所有這一切最終呼叫:
groups=np.array(groups,dtype=object)
rng = np.random.default_rng()
shuffled_indices = rng.choice(len(groups), len(groups), replace=False, p=probability_array)
shuffled_array = np.concatenate(groups[shuffled_indices]).ravel()
shuffled_array[shuffled_array < 1] = np.NaN
所有這些都非常麻煩,而且速度不是很快。除了您當然可以更好地撰寫代碼這一事實之外,我覺得我缺少一些非常簡單的問題解決方案。有人可以指出我正確的方向嗎?
uj5u.com熱心網友回復:
一種方法:
import numpy as np
from itertools import groupby
# toy data
my_array = np.array([np.nan, 1, 1, np.nan, np.nan, 2, 2, 2, np.nan, 3, 3, 3, np.nan, 4, 4, np.nan, np.nan])
# find groups
groups = np.array([[key, sum(1 for _ in group)] for key, group in groupby(my_array)])
# permute
keys, repetitions = zip(*np.random.permutation(groups))
# recreate new array
res = np.repeat(keys, repetitions)
print(res)
輸出 (單次運行)
[ 3. 3. 3. nan nan nan nan 2. 2. 2. 1. 1. nan nan nan 4. 4.]
uj5u.com熱心網友回復:
我已經在一些限制下解決了你的問題
- 我使用零作為分隔符而不是 NaN
- 我假設你的陣列總是以非零整數序列開始,以另一個非零整數序列結束。
有了這些規定,我基本上已經打亂了整數序列的表示,后來我又把所有東西縫合到位。
In [102]: import numpy as np
...: from itertools import groupby
...: a = np.array([int(_) for _ in '1110022220003044440005500000600777'])
...: print(a)
...: n, z = [], []
...: for i,g in groupby(a):
...: if i:
...: n.append((i, sum(1 for _ in g)))
...: else:
...: z.append(sum(1 for _ in g))
...: np.random.shuffle(n)
...: nn = n[0]
...: b = [*[nn[0]]*nn[1]]
...: for zz, nn in zip(z, n[1:]):
...: b = [*[0]*zz, *[nn[0]]*nn[1]]
...: print(np.array(b))
[1 1 1 0 0 2 2 2 2 0 0 0 3 0 4 4 4 4 0 0 0 5 5 0 0 0 0 0 6 0 0 7 7 7]
[7 7 7 0 0 1 1 1 0 0 0 4 4 4 4 0 6 0 0 0 5 5 0 0 0 0 0 2 2 2 2 0 0 3]
筆記
混洗后的陣列中分隔符的長度與原始陣列中的完全相同,但混洗分隔符也很容易。一個更困難的問題是任意改變長度,保持陣列長度不變。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/341069.html
