【问题标题】:Randomly generate data under conditions for sqlitesqlite条件下随机生成数据
【发布时间】:2021-05-09 09:25:02
【问题描述】:

作为创建机器学习练习的一部分,我有一个如下所示的 sqlite 数据库: “Pizza”、“DateDimension”和“Customer”表已填充,有 5 种不同的比萨饼和 10 位顾客。

如何为 sales 表生成随机数据,但给出创建模式的条件?

例如,在星期一/星期二,随机销售数字在 15 到 25 之间,在一周的其他日子随机销售数字在 10 到 20 之间,周末在 20 到 30 之间。

知道一天内,对于 ID=1 的客户销售 15 个比萨饼,ID=2 的客户销售了 2 个 ID=2 的比萨饼和 4 个 ID=3 的比萨饼, 对于 ID=2 的客户,销售了 3 个 ID=2 的比萨饼,并且
对于 ID=3 的客户,销售 3 个 ID=4 的比萨饼和 3 个 ID=2 的比萨饼。

这样一共有 15 个比萨饼,其中 8 个 ID=2 比萨饼,4 个 ID=3 比萨饼,3 个 ID=4 个比萨饼,分给三个顾客。

我不知道我的解释是否足够清楚,基本上我们每天需要一个随机的比萨销售数量,并且这个数字本身是在比萨类型和顾客之间随机分配的,在某些情况下条件,以便遵循每天销售数量的模式。

【问题讨论】:

    标签: python sqlite random


    【解决方案1】:

    我相信以下内容可能符合您的要求。

    首先,它在日期范围(见 cmets)中每 10 分钟创建一次销售额,到中间表 (initial_sales) 中将有大约 10k 左右。每个人都会有一个随机的披萨、客户和数量。

    下一个中间表 daily_sales 是从按日期分组的 initial_sales 生成的(即每个日期 1 行),除了日期是星期几(0 = Sun ..... 6= Sat)(不是真的需要)更重要的是第三列,它有一个基于星期几的随机数(CASE WHEN THEN END 结构)。

    然后查询 daily_sales 表,并为每一行生成 sql 以将数据插入 pizzeriasales 表。例如

    INSERT INTO pizzeriasales SELECT null,date(date),time(date),pizzaId,quantity,clientid FROM initial_sales WHERE date(date) = '2021-01-01' ORDER BY random() LIMIT 13;
    INSERT INTO pizzeriasales SELECT null,date(date),time(date),pizzaId,quantity,clientid FROM initial_sales WHERE date(date) = '2021-01-02' ORDER BY random() LIMIT 25;
    INSERT INTO pizzeriasales SELECT null,date(date),time(date),pizzaId,quantity,clientid FROM initial_sales WHERE date(date) = '2021-01-03' ORDER BY random() LIMIT 29;
    INSERT INTO pizzeriasales SELECT null,date(date),time(date),pizzaId,quantity,clientid FROM initial_sales WHERE date(date) = '2021-01-04' ORDER BY random() LIMIT 20;
    INSERT INTO pizzeriasales SELECT null,date(date),time(date),pizzaId,quantity,clientid FROM initial_sales WHERE date(date) = '2021-01-05' ORDER BY random() LIMIT 17;
    INSERT INTO pizzeriasales SELECT null,date(date),time(date),pizzaId,quantity,clientid FROM initial_sales WHERE date(date) = '2021-01-06' ORDER BY random() LIMIT 10;
    
    • 每个人都会从相关日期的initial_sales中选择随机行(ORDER BY random()),根据daily_sales中的数字选择行数 表。该数字是星期几的较小数字与较小数字加 10 之间的随机数。

    作为一个例子,它来自按日期分组时生成的 pizzeriasales 表,第一列显示当天的订单数。

    (12, 1, '2021-01-01', '16:10:00', 5, 3, 8)
    (23, 13, '2021-01-02', '01:40:00', 3, 3, 1)
    (28, 36, '2021-01-03', '05:00:00', 3, 1, 5)
    (16, 64, '2021-01-04', '10:10:00', 5, 2, 9)
    (22, 80, '2021-01-05', '09:10:00', 4, 2, 7)
    (14, 102, '2021-01-06', '10:10:00', 1, 1, 3)
    (20, 116, '2021-01-07', '05:50:00', 5, 2, 4)
    
    • 请注意,除了第一个值之外,重要的值 12 表示 2021 年 1 月 1 日的销售额是多少(看起来是星期五,因为 23 日和 28 日接下来的两个日期在 20- 30 范围)。

    • 注意您可能会注意到,只要日期采用 SQLite 可识别的格式 (https://sqlite.org/lang_datefunc.html),就不需要 DateDimension 表

    Pyhton 明智的做法是:-

    import sqlite3
    conn = sqlite3.connect("pizzasales.db")
    cur = conn.cursor()
    
    # Drop TABLES for clean TESTING environment
    cur.execute("DROP TABLE IF EXISTS pizzeriasales;")
    cur.execute("DROP TABLE IF EXISTS pizza")
    cur.execute("DROP TABLE IF EXISTS client")
    # Create and populate the pizza table
    cur.execute("CREATE TABLE IF NOT EXISTS pizza (id INTEGER PRIMARY KEY, name TEXT, price REAL);")
    cur.execute("INSERT INTO pizza VALUES "
                "(null,'Meat Lovers', 10.00)"
                ",(null,'Hawian',12.50)"
                ",(null,'Neopolitan',11.00)"
                ",(null,'Margerita',9.00),(null,'standard',8.00);"
                )
    # Create and populate the clieant table
    cur.execute("CREATE TABLE IF NOT EXISTS client (id INTEGER PRIMARY KEY, name TEXT, firstName TEXT);")
    cur.execute("INSERT INTO client VALUES "
                "(null,'Mary','Smith')"
                ",(null,'Fred','Bloggs')"
                ",(null,'Sarah','Bull')"
                ",(null,'Alan','Taylor')"
                ",(null,'Linda','James')"
                ",(null,'Barbara','Astley')"
                ",(null,'Mark','Jones')"
                ",(null,'Catherine','Seymour')"
                ",(null,'Charles','Page')"
                ",(null,'Alex','Howard');"
                )
    # Create the pizzeriasales table to be populated later
    cur.execute("CREATE TABLE IF NOT EXISTS pizzeriasales (id INTEGER PRIMARY KEY, date TEXT, hour TEXT, pizzaId INTEGER, quantity INTEGER, clientID INTEGER);")
    
    # Create the intermediate initial sales (individual orders every 10 minutes with random pizza and client)
    cur.execute("DROP TABLE IF EXISTS initial_sales;")
    cur.execute("CREATE TABLE IF NOT EXISTS initial_sales (date TEXT,pizzaId INTEGER, clientId INTEGER, quantity INTEGER);")
    # Populate the table (some 10000 rows)
    cur.execute("WITH "
                "cte_sales(date,pizzaId,clientId,quantity) "
                " AS (SELECT '2021-01-01 11:00'" # <<<<<<< date to start from
                ",abs(random() % (SELECT max(id) FROM pizza)) + 1" # <<<<<<<< random pizza
                ",abs(random() % (SELECT max(id) FROM client)) + 1" # <<<<<<<< random client
                ",abs(random() % 3) + 1" # <<<<<<<< random quantity
                " UNION ALL "
                " SELECT "
                "datetime(date,'+10 minute')"
                ", (1 + abs(random() % (SELECT max(id) FROM pizza)))"
                ",(1 + abs(random() % (SELECT max(id) FROM client)))"
                ",abs(random() % 3) + 1 FROM cte_sales "
                "WHERE date < '2021-03-01' " # <<<<<<< date to end on
                "LIMIT 10000" # <<<<<<<< secondary limit just in case
                ") "
                "INSERT INTO initial_sales SELECT * FROM cte_sales;"
                )
    
    # Create the base dates i.e. 1 date with the number of sales that day
    cur.execute("DROP TABLE IF EXISTS daily_sales_numbers;")
    cur.execute("CREATE TABLE IF NOT EXISTS daily_sales_numbers (date TEXT, day_in_week,number);")
    # Now populate the daily_sales_numbers
    cur.execute("WITH "
                "cte_base_dates(date,day_in_week,number) AS ("
                "SELECT "
                "date, "
                "strftime('%w',date),"
                "CASE "
                "WHEN CAST(strftime('%w',date) AS INTEGER) BETWEEN 1 AND 2 THEN 15 + abs(random() % 11) "
                "WHEN CAST(strftime('%w',date) AS INTEGER) BETWEEN 3 AND 5 THEN 10 + abs(random() % 11) "
                "ELSE 20 + abs(random() % 11) END "
                "FROM initial_sales "
                "GROUP BY date(date)"
                ") "
                "INSERT INTO daily_sales_numbers SELECT * FROM cte_base_dates;")
    
    # Now prepare to build the pizzeriasales table
    cursor = cur.execute("SELECT * FROM daily_sales_numbers;")
    sql = []
    for row in cursor:
        sql.append("INSERT INTO pizzeriasales " \
              "SELECT null,date(date),time(date),pizzaId,quantity,clientid " \
              "FROM initial_sales " \
              "WHERE "
                   "date(date) = '" + (row[0])[0:10] #<<<<<<<< date as per the respective daily_sales row
                   + "' ORDER BY random() " #<<<<<<<< random selection from the initial_sales
                     "LIMIT " + str(row[2]) #<<<<<<<< the number to include based upon the day of the week
                   + ";")
    for stmnt in sql:
        print(stmnt)
        cur.execute(stmnt)
    
    # ALL done so show the number of rows in pizzeriasales and a per date basis
    # note other data is from arbritary rows of the group (i.e. date)
    conn.commit()
    cursor = cur.execute("SELECT count(*),* FROM pizzeriasales GROUP BY date(date)")
    for row in cursor:
        print(row)
    
    cursor.close()
    conn.commit()
    cur.close()
    conn.close()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-09
      • 2019-04-25
      • 2012-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多