这是此问题的后续内容
How to create a pandas dataframe where columns are filled with random strings?
在其中给出了对具有随机字符串的完整熊猫行的解决方案。但是,该解决方案对我来说不够快,因为创建数百万行的数据需要花费很多时间,因此我需要为涉及内存错误的另一个问题创建一个最小的示例。
我尝试了以下代码
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万行随机字符串的数据帧。为此,我需要一种计算效率更高的方法,用随机字符串填充熊猫数据框。
答案 0 :(得分:2)
使用NumPy一次调用madvise
即可生成字符串数组,
而不是列表理解会调用np.random.choice
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=1000
,num_rows=10000
快26倍:
alt
请注意,在for循环中调用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
会导致quadratic copying。
收集列表中的子DataFrame,然后在循环完成后调用pd.concat
一次,效率更高:
pd.concat