2

現在、次の形式のデータフレームがあります。

step  tag_id  x_pos   y_pos
1     1         5      3
1     2         3      4
2     1         2      2
2     3         1      6
.........................
.........................
N     1         5      7

df の各行について、x 値と y 値 (独立) のガウス分布からm行のオーバーサンプリングを追加することを目指しています。したがって、N = 100 および m = 10 の df は、元の値とオーバーサンプリングされた値を含む df の長さ 1010 になります。

これのために私が持っているコードは機能しますが、大規模なデータセット (N > 100k) では非常に遅くなります。多くの操作 (新しい配列/ dfs の作成、反復子の使用など) がパフォーマンスを妨げていると確信しています。データセット全体でより高い m 値を生成できるように、パフォーマンスを向上させる方法について助けていただければ幸いです。例: 入力データは pandas データフレームからのものですが、多変量正規関数は numpy 配列で動作します。numpy 配列とデータフレーム間でコピーせずに、パンダを介してこれを実装するより自然な方法はありますか? ありがとう!

再現可能な例:

import pandas as pd
import numpy as np
import random


def gaussianOversample2(row, n):
    sigma = 2
    mean_x = float(getattr(row,'x_pos'))
    mean_y = float(getattr(row,'y_pos'))
    step = getattr(row, 'step')
    tag_id = getattr(row, 'tag_id')
    sigma = np.array([1,1])
    cov = np.diag(sigma ** 2)
    x,y = np.random.multivariate_normal([mean_x, mean_y], cov, n).T
    x = np.concatenate(([mean_x], x))
    y = np.concatenate(([mean_y], y))
    
    steps = np.empty(n+1)
    tags = np.empty(n+1)
    
    steps.fill(step)
    tags.fill(tag_id)
    
    return x,y, steps, tags
    
    
def oversampleDf(df, n):
    
    oversampled_arr = np.empty((0,4), float)
    # with input df with step, tag_id, x_pos, y_pos
    data = pd.DataFrame(columns = df.columns)
    count = 0
    for row in df.itertuples(index=False):
        count = count + 1
        temp = np.zeros((len(row), n+1))
        oversample_x, oversample_y, steps, tags = gaussianOversample2(row, n)
        temp[0] = steps
        temp[1] = tags
        temp[2] = oversample_x
        temp[3] = oversample_y
        temp = pd.DataFrame(temp.T, columns = df.columns)

        data = data.append(temp)
        if count % 1000 == 0:
            print("Row: ", count)
    return data

df = pd.DataFrame([[1, 1, 5, 3],[1, 2, 3, 4],[2, 1, 2, 2],[2, 3, 1, 6], columns = ['step', 'tag_id', 'x_pos', 'y_pos']])

res = oversampleDf(df, 20)

"""
# Result should be:
    step  tag_id     x_pos     y_pos
0    1.0     1.0  5.000000  3.000000
1    1.0     1.0  3.423492  3.886602
2    1.0     1.0  5.404581  2.177559
3    1.0     1.0  4.023274  2.883737
4    1.0     1.0  3.390710  3.038782
..   ...     ...       ...       ...
16   2.0     3.0  1.894151  5.510321
17   2.0     3.0  1.110932  5.281578
18   2.0     3.0  1.623538  4.529825
19   2.0     3.0 -0.576756  7.476872
20   2.0     3.0 -0.866123  5.898048
"""
4

1 に答える 1