引言:个人认为,“造数据”是一个数据分析师的一项基本技能,当然啦,“造数据”不是说胡编乱造,而是根据自己的需求去构造一些模拟数据集,用于测试等用途,而且使用虚拟数据不用担心数据隐私和安全问题,嘿嘿。
文章思路:random标准库 → faker第三方库 → 构造销售数据集示例
效果展示:
一、random标准库常用方法
random.seed(a=None) 可以设置随机数生成器的种子,使得每次运行时的随机数序列相同。
(一)生成整数
生成指定区间范围内的随机整数:
# 生成一个在 1 到 100 之间的随机整数
random.randint(1, 100)
(二)生成浮点数
生成指定范围内的随机浮点数,使用round控制小数精度:
# 生成一个在 10 到 100 之间的随机浮动数
random.uniform(10, 100) # 例如输出:54.7938611692445
# 保留2位小数
round(random.uniform(10, 100), 2)
(三)随机抽取、打乱序列
1、从序列中随机抽取一个元素:
# 从列表中随机选择一个元素
random.choice([1, 2, 3, 4, 5])
2、从随机序列中随机抽取k个元素,支持设置权重(每个元素被选中的概率):
# random.choices(seq, weights=None, k=1)
# 从列表中随机选择两个元素,且weights为每个元素被选中的概率
random.choices([1, 2, 3, 4, 5], weights=[0.1, 0.1, 0.3, 0.2, 0.3], k=2) # 例如输出:[3, 5]
3、与上条类似,从给定的序列中随机选择 k
个元素,返回一个新列表,原序列不受影响:
# 从列表中随机选择 3 个不重复的元素
random_sample = random.sample([1, 2, 3, 4, 5], k=3) # 例如输出:[1, 4, 3]
4、随机打乱序列:
# 将列表随机排列
lst = [1, 2, 3, 4, 5]
random.shuffle(lst) # 例如输出:[2, 5, 4, 1, 3]
(四)生成随机布尔值
1、随机生成1个随机布尔值:
# 生成一个随机浮动数,并转换为布尔值
random_bool = random.random() < 0.5
2、生成一个随机布尔序列:
list(random.random() < 0.5 for _ in range(10))
二、faker第三方库(需要下载)
faker 库是 Python 中常用的生成假数据的库,提供了大量的功能来生成各种类型的虚拟数据,如姓名、地址、日期等。以下是 faker 库的一些常用方法,按类别整理:
注:使用前一般要初始化,如下
from faker import Faker
fake = Faker()
(一)个人信息类
1、生成一个随机姓名(也可以只生成姓或名)
# 生成一个随机姓名
name = fake.name() # 例如:'John Doe'
# 生成一个随机名
first_name = fake.first_name()
# 生成一个随机姓氏
last_name = fake.last_name()
2、生成一个随机地址
# 手续代码我就不做赋值了,只列方法
fake.address()
3、生成一个随机城市、州/省份、国家
# 城市
fake.city() # 例如:'New York'
# 州/省份
fake.state() # 例如:'California'
# 国家
fake.country() # 例如:'United States'
4、电子邮件email
fake.email() # 例如:'john.doe@example.com'
5、电话号码
fake.phone_number() # 例如:'(555) 555-5555'
6、身份证
fake.ssn() # 生成一个18位的身份证号
(二)日期
生成指定时间范围内的随机日期,还要结合 datetime 库:
from faker import Faker
from datetime import date
fake = Faker()
# 使用 datetime.date() 来创建日期对象
start_date = date(2023, 1, 1)
end_date = date(2023, 12, 31)
# 生成指定范围内的随机日期
random_date = fake.date_between(start_date=start_date, end_date=end_date)
print(random_date) # 例如:'2023-06-15'
(三)文本和公司信息
# 生成一个随机的句子
fake.sentence() # 例如:'The quick brown fox jumps over the lazy dog.'
# 生成一个随机段落
fake.paragraph() # 例如:'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
# 生成一个随机的公司名称
fake.company()
# 生成一个随机的职位名称
fake.job() # 例如:'Software Engineer'
(四)用户 ID
# 生成一个随机的 UUID
fake.uuid4() # 例如:'f9a86cc4-f7f7-4686-b49b-76d1b74f9f39'
三、虚拟电商行业销售数据生成案例
生成一个有1000条记录的销售数据集,包含以下字段:用户ID、用户名、email、产品名称、购买数量、单价、消费总金额、(下单)购买日期。
from faker import Faker
from datetime import date
import pandas as pd
import random
fake = Faker() # 初始化Faker实例
# 定义电商数据生成函数
def func(data_size):
datas = []
for i in range(data_size):
# 生成用户id
id = str(fake.uuid4())
# 生成用户名字
name = fake.name()
# 生成用户邮箱
email = fake.email()
# 生成商品名称
product_name = fake.word()
# 生成购买数量
quantity = random.randint(1,10)
# 生成单价。使用uniform生成a~b之间的随机浮动数,并使用round保留两位小数
unit_price = round(random.uniform(50,200), 2)
# 生成同消费金额
total_price = round(quantity*unit_price, 2)
# 随机生成2024上半年这个时间段的购买日期
sale_date = fake.date_between(start_date=date(2024,1,1), end_date=date(2024,6,30))
datas.append({
'id': id,
'name': name,
'email': email,
'product_name': product_name,
'quantity': quantity,
'unit_price': unit_price,
'total_price': total_price,
'sale_date': sale_date
})
return pd.DataFrame(datas) # 将数据转化为DataFrame形式,作为返回值
# 测试入口
data_size = 1000 # 确定要造的数据数量
df = func(data_size)
print(df.head(5))
输出前5条数据,如下:
但是,这样的数据集是存在问题的,为什么呢?
因为数据集是销售数据,存储的是用户下单的历史记录,用户可能不止一次下单购买,换句话来说,在数据集中,用户id 是可能重复的,出现重复id表示该id的用户下单多次,但是按照上面的方法生成的数据集,id 是没有重复的。
怎么解决?往下看代码,增加了一个_generate_ids函数用于生成1000条包含id可以重复的数据:
from faker import Faker
from datetime import date
import pandas as pd
import random
fake = Faker() # 初始化Faker实例
# 定义生成可重复ID的函数,其中参数ration为重复的ID占比,比如0.3
def _generate_ids(data_sizes, ration):
# 计算重复的id数
num_dupl = int(data_sizes*ration)
# 先生成一部分不重复的id
ids = [str(fake.uuid4()) for _ in range(data_sizes - num_dupl)]
# 随机抽取一部分id来重复
ids.extend(random.sample(ids, num_dupl))
# 打乱顺序
random.shuffle(ids)
return ids
# 定义生成数据的函数
def func(data_sizes, ration):
datas = []
ids = _generate_ids(data_sizes, ration)
for id in ids:
# 生成用户名字
name = fake.name()
# 生成用户邮箱
email = fake.email()
# 生成商品名称
product_name = fake.word()
# 生成购买数量
quantity = random.randint(1,10)
# 生成单价。使用uniform生成50~200之间的随机浮动数,并使用round保留两位小数
unit_price = round(random.uniform(50,200), 2)
# 生成同消费金额
total_price = round(quantity*unit_price, 2)
# 随机生成2024上半年这个时间段的购买日期
sale_date = fake.date_between(start_date=date(2024,1,1), end_date=date(2024,6,30))
datas.append({
'id': id,
'name': name,
'email': email,
'product_name': product_name,
'quantity': quantity,
'unit_price': unit_price,
'total_price': total_price,
'sale_date': sale_date
})
return pd.DataFrame(datas) # 将数据转化为DataFrame形式,作为返回值
data_size = 1000 # 确定要造的数据数量
ration = 0.3 # 确定重复比例
df = func(data_size, ration)
# 查找 'id' 列中重复的行
df[df.duplicated(subset='id')]
找出并输出 id 重复的行(即记录),可以发现刚好有300条数据重复,符合代码里设置的含0.3重复数据的比例。
当然了,其他字段(列名)如果也要求可以有重复 ,可以按照类似方法更改代码。
以增加一个可以重复的 “商品类别” 字段为例,:
# 先确定类别有几类,假如有5个类别
producct_categories = ['A', 'B', 'C', 'D', 'E'] # 方法一:手动定义
# 最后随机挑取一个类别作为该条数据的类别即可
category = random.choice(producct_categories)
# ——————————————————————————————————————————
# 先确定类别有几类,假如有5个类别
producct_categories = [fake.word() for _ in range(5)] #方法二:fake.word()函数,生成一个单词作为类别名称
# 最后随机挑取一个类别作为该条数据的类别即可
category = random.choice(producct_categories)
到这里,虚拟销售数据的生成就到此结束啦,还有一个点,就是可以生成中文数据,只需要更改下面一行代码的参数:
# 初始化Faker实例的时候,加入参数"zh_CN"就可以了,不写参数则默认生成英文数据
fake = Faker("zh_CN")
更改语言后的效果如下 :