我正在尝试生成一个数据集,其中给定年份范围内的每一天都有固定数量的商店。反过来,每家商店销售固定数量的产品。特定于每个商店和日期的产品具有销售额值 (£( 和销售的产品数量。
但是,运行这些 for 循环需要一段时间来创建数据集。
无论如何我可以提高代码的效率吗?
# Generate one row Dataframes (for concatenation) for each product, in each store, on each date
dataframes = []
for d in datelist:
for s in store_IDs:
for p in product_IDs:
products_sold = random.randint(1,101)
sales = random.randint(100,1001)
data_dict = {'Date': [d], 'Store ID': [s], 'Product ID': [p], 'Sales': [sales], 'Number of Products Sold': [products_sold]}
dataframe = pd.DataFrame(data_dict)
dataframes.append(dataframe)
test_dataframe = pd.concat(dataframes)
你的代码现在非常慢的主要原因是你把数据帧构造埋在三重循环中。 这不是必需的。 现在,您正在每个循环内创建一个新的数据帧。 以某种类型的格式创建所有数据的效率要高得多,pandas
可以引入,然后创建一次数据帧。
对于您拥有的结构,您可以做的最简单的 mod 是制作数据行列表,像现在构建的那样为每一行在该列表中附加一个新字典,然后从字典列表中创建一个 df... 熊猫知道如何做到这一点。 我还删除了字典中项目的列表括号。 那没有必要。
import pandas as pd
import random
datelist = [1, 2, 4, 55]
store_IDs = ['6A', '27B', '12C']
product_IDs = ['soap', 'gum']
data = [] # I just renamed this for clarity
for d in datelist:
for s in store_IDs:
for p in product_IDs:
products_sold = random.randint(1,101)
sales = random.randint(100,1001)
data_dict = {'Date': d, 'Store ID': s, 'Product ID': p, 'Sales': sales, 'Number of Products Sold': products_sold}
data.append(data_dict) # this is building a list of dictionaries...
print(data[:3])
df = pd.DataFrame(data)
print(df.head())
收益 率:
[{'Date': 1, 'Store ID': '6A', 'Product ID': 'soap', 'Sales': 310, 'Number of Products Sold': 35}, {'Date': 1, 'Store ID': '6A', 'Product ID': 'gum', 'Sales': 149, 'Number of Products Sold': 34}, {'Date': 1, 'Store ID': '27B', 'Product ID': 'soap', 'Sales': 332, 'Number of Products Sold': 60}]
Date Store ID Product ID Sales Number of Products Sold
0 1 6A soap 310 35
1 1 6A gum 149 34
2 1 27B soap 332 60
3 1 27B gum 698 21
4 1 12C soap 658 51
[Finished in 0.6s]
你意识到你的尺寸很大吗?
大小约为 3 年半(以天为单位(= 1277 乘以 乘以 99 个商店 = 126,423 乘以 8999 个产品 = 1,137,680,577 行。
如果您需要平均 16 个字节(这已经不多了(,您至少需要 17GB 的内存!
出于这个原因,Store_IDs
和Product_IDs
实际上应该只是小整数,就像更具描述性名称的表中的索引一样。
提高效率的方法是减少函数调用! 例如,您可以使用numpy
随机数生成来批量生成随机值。
假设所有涉及的数字都可以容纳 16 位,这里有一个解决方案来解决您的问题(仍然需要大量内存(:
import pandas as pd
import numpy as np
def gen_data(datelist, store_IDs, product_IDs):
date16 = np.arange(len(datelist), dtype=np.int16)
store16 = np.arange(len(store_IDs), dtype=np.int16)
product16 = np.arange(len(product_IDs), dtype=np.int16)
A = np.array(np.meshgrid(date16, store16, product16), dtype=np.int16).reshape(3,-1)
length = A.shape[1]
sales = np.random.randint(100, 1001, size=(1,length), dtype=np.int16)
sold = np.random.randint(1, 101, size=(1,length), dtype=np.int16)
data = np.concatenate((A,sales,sold), axis=0)
df = pd.DataFrame(data.T, columns=['Date index', 'Store ID index', 'Product ID index', 'Sales', 'Number of Products Sold'], dtype=np.int16)
return df
FWIW 在我的机器上,我获得:
Date Store ID Product ID Sales Number of Products Sold
0 0 0 0 127 85
1 0 0 1 292 37
2 0 0 2 180 36
3 0 0 3 558 88
4 0 0 4 519 79
... ... ... ... ... ...
1137680572 1276 98 8994 932 78
1137680573 1276 98 8995 401 47
1137680574 1276 98 8996 840 77
1137680575 1276 98 8997 717 91
1137680576 1276 98 8998 632 24
[1137680577 rows x 5 columns]
real 1m16.325s
user 0m22.086s
sys 0m25.800s
(我没有足够的内存并使用交换(