簡體   English   中英

創建大熊貓數據框的最快/計算效率最高的方法,其中的列填充有幾百萬行的隨機字符串?

[英]Fastest/most computationally efficient way to create a pandas dataframe where columns are filled with random strings, for several million rows?

這是此問題的后續措施

如何創建一個用隨機字符串填充列的熊貓數據框?

在其中給出了對帶有隨機字符串的完整熊貓行的解決方案。 但是,該解決方案對我來說不夠快,因為創建數百萬行的數據需要花費很多時間,因此我需要為涉及內存錯誤的另一個問題創建一個最小的示例。

我嘗試了以下代碼

from random import randint
import string
import numpy as np
import pandas as pd
import random
draw = randint(200, 5500)
def id_generator(size=draw, chars=string.ascii_uppercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))

num_rows =10000
data = np.array([id_generator() for i in range(2*num_rows)]).reshape(-1,2)
dfAll = pd.DataFrame(data)

#original is 65
for i in range(300):
    print('step ', i)
    draw = randint(200, 5500)
    data = np.array([id_generator() for i in range(2*num_rows)]).reshape(-1,2)
    df = pd.DataFrame(data)
    dfAll = pd.concat([ df,  dfAll ])


我正在使用帶有塊的append方法制作數據幀,否則如果一次執行所有操作,將會出現內存錯誤。

我使用Google合作實驗室作為我的環境。 我希望得到的結果是,它在1小時內生成了600萬行隨機字符串的數據幀。 為此,我需要一種計算效率更高的方法,用隨機字符串填充熊貓數據框。

使用NumPy只需一次調用np.random.choice即可生成字符串數組,而不是使用列表id_generator來調用id_generator 2*num_rows次(並調用random.choice 2*num_rows*size次):

import string
import numpy as np
import pandas as pd
from random import randint
import random

def make_random_str_array(size=10, num_rows=100, chars=string.ascii_uppercase + string.digits):
    return (np.random.choice(list(chars), num_rows*size)
            .view('|U{}'.format(size)))

def id_generator(size, chars=string.ascii_uppercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))

def orig(size, num_rows):
    data = np.array([id_generator(size=size) for i in range(2*num_rows)]).reshape(-1, 2)
    dfAll = pd.DataFrame(data)
    return dfAll

def alt(size, num_rows):
    data = make_random_str_array(size, num_rows=2*num_rows).reshape(-1, 2)
    dfAll = pd.DataFrame(data)
    return dfAll

對於size=1000num_rows=10000alt快26倍:

In [94]: %timeit orig(1000, 10000)
9.22 s ± 49.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [95]: %timeit alt(1000, 10000)
343 ms ± 2.85 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [97]: 9220/343
Out[98]: 26.88046647230321

請注意,在for循環中調用pd.concat會導致二次復制 這是更有效地收集在一個列表中的子DataFrames,然后調用pd.concat 一旦循環完成后:

parts = []
for i in range(300):
    print('step ', i)
    size = random.randint(200, 5500)
    data = make_random_str_array(size, num_rows=2*num_rows).reshape(-1, 2)
    parts.append(pd.DataFrame(data))
dfAll = pd.concat(parts)

暫無
暫無

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

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