mdbq 2.9.7__py3-none-any.whl → 2.9.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mdbq/aggregation/query_data.py +1586 -1207
- mdbq/aggregation/query_data_bak.py +2423 -0
- mdbq/dataframe/converter.py +3 -3
- mdbq/mysql/mysql.py +3 -2
- mdbq/mysql/s_query.py +1 -0
- {mdbq-2.9.7.dist-info → mdbq-2.9.9.dist-info}/METADATA +1 -1
- {mdbq-2.9.7.dist-info → mdbq-2.9.9.dist-info}/RECORD +9 -8
- {mdbq-2.9.7.dist-info → mdbq-2.9.9.dist-info}/WHEEL +0 -0
- {mdbq-2.9.7.dist-info → mdbq-2.9.9.dist-info}/top_level.txt +0 -0
mdbq/aggregation/query_data.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# -*- coding: UTF-8 –*-
|
2
2
|
import re
|
3
3
|
import socket
|
4
|
-
from mdbq.mongo import mongo
|
5
4
|
from mdbq.mysql import mysql
|
6
5
|
from mdbq.mysql import s_query
|
7
6
|
from mdbq.aggregation import optimize_data
|
@@ -19,12 +18,6 @@ import os
|
|
19
18
|
import time
|
20
19
|
|
21
20
|
"""
|
22
|
-
程序用于下载数据库(调用 s_query.py 下载并清洗), 并对数据进行聚合清洗, 不会更新数据库信息;
|
23
|
-
|
24
|
-
添加新库流程:
|
25
|
-
1. 在 MysqlDatasQuery 类中创建函数,从数据库取出数据
|
26
|
-
2. 在 GroupBy 类中创建函数,处理聚合数据
|
27
|
-
3. 在 data_aggregation 类中添加 data_dict 字典键值,回传数据到数据库
|
28
21
|
|
29
22
|
"""
|
30
23
|
username, password, host, port, service_database = None, None, None, None, None,
|
@@ -40,61 +33,13 @@ elif socket.gethostname() in ['company', 'Mac2.local']:
|
|
40
33
|
service_database = {'company': 'mysql'}
|
41
34
|
if not username:
|
42
35
|
print(f'找不到主机:')
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
self.output: 数据库默认导出目录
|
51
|
-
self.is_maximize: 是否最大转化数据
|
52
|
-
"""
|
53
|
-
def __init__(self, target_service):
|
54
|
-
# target_service 从哪个服务器下载数据
|
55
|
-
self.months = 0 # 下载几个月数据, 0 表示当月, 1 是上月 1 号至今
|
56
|
-
# 实例化一个下载类
|
57
|
-
self.download = mongo.DownMongo(username=username, password=password, host=host, port=port, save_path=None)
|
58
|
-
|
59
|
-
def tg_wxt(self):
|
60
|
-
self.download.start_date, self.download.end_date = self.months_data(num=self.months)
|
61
|
-
projection = {
|
62
|
-
'日期': 1,
|
63
|
-
'场景名字': 1,
|
64
|
-
'主体id': 1,
|
65
|
-
'花费': 1,
|
66
|
-
'展现量': 1,
|
67
|
-
'点击量': 1,
|
68
|
-
'总购物车数': 1,
|
69
|
-
'总成交笔数': 1,
|
70
|
-
'总成交金额': 1,
|
71
|
-
'自然流量曝光量': 1,
|
72
|
-
'直接成交笔数': 1,
|
73
|
-
'直接成交金额': 1,
|
74
|
-
}
|
75
|
-
df = self.download.data_to_df(
|
76
|
-
db_name='推广数据2',
|
77
|
-
collection_name='主体报表',
|
78
|
-
projection=projection,
|
79
|
-
)
|
80
|
-
return df
|
81
|
-
|
82
|
-
@staticmethod
|
83
|
-
def days_data(days, end_date=None):
|
84
|
-
""" 读取近 days 天的数据 """
|
85
|
-
if not end_date:
|
86
|
-
end_date = datetime.datetime.now()
|
87
|
-
start_date = end_date - datetime.timedelta(days=days)
|
88
|
-
return pd.to_datetime(start_date), pd.to_datetime(end_date)
|
89
|
-
|
90
|
-
@staticmethod
|
91
|
-
def months_data(num=0, end_date=None):
|
92
|
-
""" 读取近 num 个月的数据, 0 表示读取当月的数据 """
|
93
|
-
if not end_date:
|
94
|
-
end_date = datetime.datetime.now()
|
95
|
-
start_date = end_date - relativedelta(months=num) # n 月以前的今天
|
96
|
-
start_date = f'{start_date.year}-{start_date.month}-01' # 替换为 n 月以前的第一天
|
97
|
-
return pd.to_datetime(start_date), pd.to_datetime(end_date)
|
36
|
+
m_engine = mysql.MysqlUpload(
|
37
|
+
username=username,
|
38
|
+
password=password,
|
39
|
+
host=host,
|
40
|
+
port=port,
|
41
|
+
charset='utf8mb4'
|
42
|
+
)
|
98
43
|
|
99
44
|
|
100
45
|
class MysqlDatasQuery:
|
@@ -106,6 +51,9 @@ class MysqlDatasQuery:
|
|
106
51
|
self.months = 0 # 下载几个月数据, 0 表示当月, 1 是上月 1 号至今
|
107
52
|
# 实例化一个下载类
|
108
53
|
self.download = s_query.QueryDatas(username=username, password=password, host=host, port=port)
|
54
|
+
self.update_service = True # 调试时加,true: 将数据写入 mysql 服务器
|
55
|
+
self.pf_datas = []
|
56
|
+
self.pf_datas_jd = [] # 京东聚合销售表
|
109
57
|
|
110
58
|
@staticmethod
|
111
59
|
def try_except(func): # 在类内部定义一个异常处理方法
|
@@ -118,8 +66,8 @@ class MysqlDatasQuery:
|
|
118
66
|
|
119
67
|
return wrapper
|
120
68
|
|
121
|
-
@try_except
|
122
|
-
def tg_wxt(self):
|
69
|
+
# @try_except
|
70
|
+
def tg_wxt(self, db_name='聚合数据', table_name='天猫_主体报表', is_maximize=True):
|
123
71
|
start_date, end_date = self.months_data(num=self.months)
|
124
72
|
projection = {
|
125
73
|
'日期': 1,
|
@@ -143,10 +91,100 @@ class MysqlDatasQuery:
|
|
143
91
|
end_date=end_date,
|
144
92
|
projection=projection,
|
145
93
|
)
|
146
|
-
|
94
|
+
df.rename(columns={
|
95
|
+
'场景名字': '营销场景',
|
96
|
+
'主体id': '商品id',
|
97
|
+
'总购物车数': '加购量',
|
98
|
+
'总成交笔数': '成交笔数',
|
99
|
+
'总成交金额': '成交金额'
|
100
|
+
}, inplace=True)
|
101
|
+
df = df.astype({
|
102
|
+
'商品id': str,
|
103
|
+
'花费': float,
|
104
|
+
'展现量': int,
|
105
|
+
'点击量': int,
|
106
|
+
'加购量': int,
|
107
|
+
'成交笔数': int,
|
108
|
+
'成交金额': float,
|
109
|
+
'自然流量曝光量': int,
|
110
|
+
'直接成交笔数': int,
|
111
|
+
'直接成交金额': float,
|
112
|
+
}, errors='raise')
|
113
|
+
if is_maximize:
|
114
|
+
df = df.groupby(['日期', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量'], as_index=False).agg(
|
115
|
+
**{'加购量': ('加购量', np.max),
|
116
|
+
'成交笔数': ('成交笔数', np.max),
|
117
|
+
'成交金额': ('成交金额', np.max),
|
118
|
+
'自然流量曝光量': ('自然流量曝光量', np.max),
|
119
|
+
'直接成交笔数': ('直接成交笔数', np.max),
|
120
|
+
'直接成交金额': ('直接成交金额', np.max)
|
121
|
+
}
|
122
|
+
)
|
123
|
+
else:
|
124
|
+
df = df.groupby(['日期', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量'], as_index=False).agg(
|
125
|
+
**{
|
126
|
+
'加购量': ('加购量', np.min),
|
127
|
+
'成交笔数': ('成交笔数', np.min),
|
128
|
+
'成交金额': ('成交金额', np.min),
|
129
|
+
'自然流量曝光量': ('自然流量曝光量', np.min),
|
130
|
+
'直接成交笔数': ('直接成交笔数', np.max),
|
131
|
+
'直接成交金额': ('直接成交金额', np.max)
|
132
|
+
}
|
133
|
+
)
|
134
|
+
df.insert(loc=1, column='推广渠道', value='万相台无界版') # df中插入新列
|
135
|
+
set_typ = {
|
136
|
+
'日期': 'date',
|
137
|
+
'推广渠道': 'varchar(100)',
|
138
|
+
'店铺名称': 'varchar(100)',
|
139
|
+
'营销场景': 'varchar(100)',
|
140
|
+
'商品id': 'bigint',
|
141
|
+
'花费': 'decimal(12,2)',
|
142
|
+
'展现量': 'int',
|
143
|
+
'点击量': 'int',
|
144
|
+
'加购量': 'int',
|
145
|
+
'成交笔数': 'int',
|
146
|
+
'成交金额': 'decimal(12,2)',
|
147
|
+
'自然流量曝光量': 'int',
|
148
|
+
'直接成交笔数': 'int',
|
149
|
+
'直接成交金额': 'decimal(12,2)',
|
150
|
+
}
|
151
|
+
self.pf_datas.append(
|
152
|
+
{
|
153
|
+
'集合名称': table_name,
|
154
|
+
'数据主体': df[['日期', '店铺名称', '商品id', '花费', '成交金额', '直接成交金额']]
|
155
|
+
}
|
156
|
+
) # 制作其他聚合表
|
157
|
+
self.pf_datas.append(
|
158
|
+
{
|
159
|
+
'集合名称': '天猫汇总表调用',
|
160
|
+
'数据主体': df[
|
161
|
+
['日期', '店铺名称', '推广渠道', '营销场景', '商品id', '花费', '展现量', '点击量', '加购量',
|
162
|
+
'成交笔数', '成交金额', '直接成交笔数', '直接成交金额', '自然流量曝光量']]
|
163
|
+
}
|
164
|
+
) # 制作其他聚合表
|
165
|
+
if not self.update_service:
|
166
|
+
return
|
167
|
+
min_date = df['日期'].min()
|
168
|
+
max_date = df['日期'].max()
|
169
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
170
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
171
|
+
m_engine.df_to_mysql(
|
172
|
+
df=df,
|
173
|
+
db_name=db_name,
|
174
|
+
table_name=table_name,
|
175
|
+
icm_update=['日期', '推广渠道', '营销场景', '商品id', '花费'], # 增量更新, 在聚合数据中使用,其他不要用
|
176
|
+
move_insert=False, # 先删除,再插入
|
177
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
178
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
179
|
+
count=None,
|
180
|
+
filename=None, # 用来追踪处理进度
|
181
|
+
reset_id=False, # 是否重置自增列
|
182
|
+
set_typ=set_typ,
|
183
|
+
)
|
184
|
+
return True
|
147
185
|
|
148
186
|
@try_except
|
149
|
-
def syj(self):
|
187
|
+
def syj(self, db_name='聚合数据', table_name='生意经_宝贝指标'):
|
150
188
|
start_date, end_date = self.months_data(num=self.months)
|
151
189
|
projection = {
|
152
190
|
'日期': 1,
|
@@ -169,10 +207,71 @@ class MysqlDatasQuery:
|
|
169
207
|
end_date=end_date,
|
170
208
|
projection=projection,
|
171
209
|
)
|
172
|
-
|
210
|
+
df['宝贝id'] = df['宝贝id'].astype(str)
|
211
|
+
df = df.groupby(['日期', '店铺名称', '宝贝id', '行业类目'], as_index=False).agg(
|
212
|
+
**{'销售额': ('销售额', np.min),
|
213
|
+
'销售量': ('销售量', np.min),
|
214
|
+
'订单数': ('订单数', np.min),
|
215
|
+
'退货量': ('退货量', np.max),
|
216
|
+
'退款额': ('退款额', np.max),
|
217
|
+
'退款额_发货后': ('退款额_发货后', np.max),
|
218
|
+
'退货量_发货后': ('退货量_发货后', np.max),
|
219
|
+
}
|
220
|
+
)
|
221
|
+
df['件均价'] = df.apply(lambda x: x['销售额'] / x['销售量'] if x['销售量'] > 0 else 0, axis=1).round(
|
222
|
+
0) # 两列运算, 避免除以0
|
223
|
+
df['价格带'] = df['件均价'].apply(
|
224
|
+
lambda x: '2000+' if x >= 2000
|
225
|
+
else '1000+' if x >= 1000
|
226
|
+
else '500+' if x >= 500
|
227
|
+
else '300+' if x >= 300
|
228
|
+
else '300以下'
|
229
|
+
)
|
230
|
+
set_typ = {
|
231
|
+
'日期': 'date',
|
232
|
+
'推广渠道': 'varchar(100)',
|
233
|
+
'店铺名称': 'varchar(100)',
|
234
|
+
'宝贝id': 'bigint',
|
235
|
+
'行业类目': 'varchar(255)',
|
236
|
+
'销售额': 'decimal(12,2)',
|
237
|
+
'销售量': 'int',
|
238
|
+
'订单数': 'int',
|
239
|
+
'退货量': 'int',
|
240
|
+
'退款额': 'decimal(12,2)',
|
241
|
+
'退款额_发货后': 'decimal(12,2)',
|
242
|
+
'退货量_发货后': 'int',
|
243
|
+
'件均价': 'mediumint',
|
244
|
+
'价格带': 'varchar(100)',
|
245
|
+
}
|
246
|
+
self.pf_datas.append(
|
247
|
+
{
|
248
|
+
'集合名称': table_name,
|
249
|
+
'数据主体': df[['日期', '店铺名称', '宝贝id', '销售额', '销售量', '退款额_发货后', '退货量_发货后']]
|
250
|
+
}
|
251
|
+
) # 制作其他聚合表
|
252
|
+
if not self.update_service:
|
253
|
+
return
|
254
|
+
min_date = df['日期'].min()
|
255
|
+
max_date = df['日期'].max()
|
256
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
257
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
258
|
+
m_engine.df_to_mysql(
|
259
|
+
df=df,
|
260
|
+
db_name=db_name,
|
261
|
+
table_name=table_name,
|
262
|
+
icm_update=['日期', '宝贝id'], # 增量更新, 在聚合数据中使用,其他不要用
|
263
|
+
move_insert=False, # 先删除,再插入
|
264
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
265
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
266
|
+
count=None,
|
267
|
+
filename=None, # 用来追踪处理进度
|
268
|
+
reset_id=False, # 是否重置自增列
|
269
|
+
set_typ=set_typ,
|
270
|
+
)
|
271
|
+
return True
|
173
272
|
|
174
273
|
@try_except
|
175
|
-
def tg_rqbb(self):
|
274
|
+
def tg_rqbb(self, db_name='聚合数据', table_name='天猫_人群报表', is_maximize=True):
|
176
275
|
start_date, end_date = self.months_data(num=self.months)
|
177
276
|
projection = {
|
178
277
|
'日期': 1,
|
@@ -196,10 +295,166 @@ class MysqlDatasQuery:
|
|
196
295
|
end_date=end_date,
|
197
296
|
projection=projection,
|
198
297
|
)
|
199
|
-
|
298
|
+
df.rename(columns={
|
299
|
+
'场景名字': '营销场景',
|
300
|
+
'主体id': '商品id',
|
301
|
+
'总购物车数': '加购量',
|
302
|
+
'总成交笔数': '成交笔数',
|
303
|
+
'总成交金额': '成交金额'
|
304
|
+
}, inplace=True)
|
305
|
+
df.fillna(0, inplace=True)
|
306
|
+
df = df.astype({
|
307
|
+
'商品id': str,
|
308
|
+
'花费': float,
|
309
|
+
'展现量': int,
|
310
|
+
'点击量': int,
|
311
|
+
'加购量': int,
|
312
|
+
'成交笔数': int,
|
313
|
+
'成交金额': float,
|
314
|
+
'直接成交笔数': int,
|
315
|
+
'直接成交金额': float,
|
316
|
+
}, errors='raise')
|
317
|
+
if is_maximize:
|
318
|
+
df = df.groupby(['日期', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量', '人群名字'],
|
319
|
+
as_index=False).agg(
|
320
|
+
**{'加购量': ('加购量', np.max),
|
321
|
+
'成交笔数': ('成交笔数', np.max),
|
322
|
+
'成交金额': ('成交金额', np.max),
|
323
|
+
'直接成交笔数': ('直接成交笔数', np.max),
|
324
|
+
'直接成交金额': ('直接成交金额', np.max)
|
325
|
+
}
|
326
|
+
)
|
327
|
+
else:
|
328
|
+
df = df.groupby(['日期', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量', '人群名字'],
|
329
|
+
as_index=False).agg(
|
330
|
+
**{
|
331
|
+
'加购量': ('加购量', np.min),
|
332
|
+
'成交笔数': ('成交笔数', np.min),
|
333
|
+
'成交金额': ('成交金额', np.min),
|
334
|
+
'直接成交笔数': ('直接成交笔数', np.max),
|
335
|
+
'直接成交金额': ('直接成交金额', np.max)
|
336
|
+
}
|
337
|
+
)
|
338
|
+
df.insert(loc=1, column='推广渠道', value='万相台无界版') # df中插入新列
|
339
|
+
# 1. 匹配 L后面接 2 个或以上数字,不区分大小写,示例:L345
|
340
|
+
# 2. 其余情况,L 后面接多个数字的都会被第一条 if 命中,不区分大小写
|
341
|
+
df['消费力层级'] = df.apply(
|
342
|
+
lambda x:
|
343
|
+
''.join(re.findall(r'(l\d+)', x['人群名字'].upper(), re.IGNORECASE)) if re.findall(r'(l\d{2,})',
|
344
|
+
x['人群名字'],
|
345
|
+
re.IGNORECASE)
|
346
|
+
else 'L5' if re.findall(r'(l\d*5)', x['人群名字'], re.IGNORECASE)
|
347
|
+
else 'L4' if re.findall(r'(l\d*4)', x['人群名字'], re.IGNORECASE)
|
348
|
+
else 'L3' if re.findall(r'(l\d*3)', x['人群名字'], re.IGNORECASE)
|
349
|
+
else 'L2' if re.findall(r'(l\d*2)', x['人群名字'], re.IGNORECASE)
|
350
|
+
else 'L1' if re.findall(r'(l\d*1)', x['人群名字'], re.IGNORECASE)
|
351
|
+
else '', axis=1)
|
352
|
+
# 1. 匹配连续的 4 个数字且后面不能接数字或"元"或汉字,筛掉的人群示例:月均消费6000元|受众20240729175213|xxx2024真皮公文包
|
353
|
+
# 2. 匹配 2数字_2数字且前面不能是数字,合法匹配:人群_30_50_促; 非法示例:L345_3040 避免识别出 35~20 岁用户的情况
|
354
|
+
# pattern = r'(\d{4})(?!\d|[\u4e00-\u9fa5])' # 匹配 4 个数字,后面不能接数字或汉字
|
355
|
+
# pattern = r'(?<![\d\u4e00-\u9fa5])(\d{4})' # 匹配前面不是数字或汉字的 4 个连续数字
|
356
|
+
|
357
|
+
# 匹配 4 个数字,前面和后面都不能是数字或汉字
|
358
|
+
pattern1 = r'(?<![\d\u4e00-\u9fa5])(\d{4})(?!\d|[\u4e00-\u9fa5])'
|
359
|
+
# 匹配指定字符,前面不能是数字或 l 或 L 开头
|
360
|
+
pattern2 = r'(?<![\dlL])(\d{2}_\d{2})'
|
361
|
+
df['用户年龄'] = df.apply(
|
362
|
+
lambda x:
|
363
|
+
''.join(re.findall(pattern1, x['人群名字'].upper())) if re.findall(pattern1, x['人群名字'])
|
364
|
+
# else ''.join(re.findall(r'[^\d|l|L](\d{2}_\d{2})', x['人群名字'].upper())) if re.findall(r'[^\d|l|L](\d{2}_\d{2})', x['人群名字'])
|
365
|
+
else ''.join(re.findall(pattern2, x['人群名字'].upper())) if re.findall(pattern2, x['人群名字'])
|
366
|
+
else ''.join(re.findall(r'(\d{2}-\d{2})岁', x['人群名字'].upper())) if re.findall(r'(\d{2}-\d{2})岁',
|
367
|
+
x['人群名字'])
|
368
|
+
else '', axis=1)
|
369
|
+
df['用户年龄'] = df['用户年龄'].apply(
|
370
|
+
lambda x: f'{x[:2]}~{x[2:4]}' if str(x).isdigit()
|
371
|
+
else str(x).replace('_', '~') if '_' in x
|
372
|
+
else str(x).replace('-', '~') if '-' in x
|
373
|
+
else x
|
374
|
+
)
|
375
|
+
# 年龄层不能是 0 开头
|
376
|
+
df['用户年龄'] = df['用户年龄'].apply(
|
377
|
+
lambda x: '' if str(x).startswith('0') else x)
|
378
|
+
# df = df.head(1000)
|
379
|
+
# df.to_csv('/Users/xigua/Downloads/test.csv', index=False, header=True, encoding='utf-8_sig')
|
380
|
+
# breakpoint()
|
381
|
+
|
382
|
+
# 下面是添加人群 AIPL 分类
|
383
|
+
dir_file = f'\\\\192.168.1.198\\时尚事业部\\01.运营部\\0-电商周报-每周五更新\\分类配置文件.xlsx'
|
384
|
+
dir_file2 = '/Volumes/时尚事业部/01.运营部/0-电商周报-每周五更新/分类配置文件.xlsx'
|
385
|
+
if platform.system() == 'Windows':
|
386
|
+
dir_file3 = 'C:\\同步空间\\BaiduSyncdisk\\原始文件2\\分类配置文件.xlsx'
|
387
|
+
else:
|
388
|
+
dir_file3 = '/Users/xigua/数据中心/原始文件2/分类配置文件.xlsx'
|
389
|
+
if not os.path.isfile(dir_file):
|
390
|
+
dir_file = dir_file2
|
391
|
+
if not os.path.isfile(dir_file):
|
392
|
+
dir_file = dir_file3
|
393
|
+
if os.path.isfile(dir_file):
|
394
|
+
df_fl = pd.read_excel(dir_file, sheet_name='人群分类', header=0)
|
395
|
+
df_fl = df_fl[['人群名字', '人群分类']]
|
396
|
+
# 合并并获取分类信息
|
397
|
+
df = pd.merge(df, df_fl, left_on=['人群名字'], right_on=['人群名字'], how='left')
|
398
|
+
df['人群分类'].fillna('', inplace=True)
|
399
|
+
if '人群分类' in df.columns.tolist():
|
400
|
+
# 这行决定了,从文件中读取的分类信息优先级高于内部函数的分类规则
|
401
|
+
# 这个 lambda 适配人群名字中带有特定标识的分类,强匹配
|
402
|
+
df['人群分类'] = df.apply(
|
403
|
+
lambda x: self.set_crowd(keyword=str(x['人群名字']), as_file=False) if x['人群分类'] == ''
|
404
|
+
else x['人群分类'], axis=1
|
405
|
+
)
|
406
|
+
# 这个 lambda 适配人群名字中聚类的特征字符,弱匹配
|
407
|
+
df['人群分类'] = df.apply(
|
408
|
+
lambda x: self.set_crowd2(keyword=str(x['人群名字']), as_file=False) if x['人群分类'] == ''
|
409
|
+
else x['人群分类'], axis=1
|
410
|
+
)
|
411
|
+
else:
|
412
|
+
df['人群分类'] = df['人群名字'].apply(lambda x: self.set_crowd(keyword=str(x), as_file=False))
|
413
|
+
df['人群分类'] = df.apply(
|
414
|
+
lambda x: self.set_crowd2(keyword=str(x['人群名字']), as_file=False) if x['人群分类'] == ''
|
415
|
+
else x['人群分类'], axis=1
|
416
|
+
)
|
417
|
+
df['人群分类'] = df['人群分类'].apply(lambda x: str(x).upper() if x else x)
|
418
|
+
set_typ = {
|
419
|
+
'日期': 'date',
|
420
|
+
'推广渠道': 'varchar(100)',
|
421
|
+
'店铺名称': 'varchar(100)',
|
422
|
+
'营销场景': 'varchar(100)',
|
423
|
+
'商品id': 'bigint',
|
424
|
+
'花费': 'decimal(10,2)',
|
425
|
+
'展现量': 'int',
|
426
|
+
'点击量': 'int',
|
427
|
+
'人群名字': 'varchar(255)',
|
428
|
+
'加购量': 'int',
|
429
|
+
'成交笔数': 'int',
|
430
|
+
'成交金额': 'decimal(12,2)',
|
431
|
+
'直接成交笔数': 'int',
|
432
|
+
'直接成交金额': 'decimal(12,2)',
|
433
|
+
'消费力层级': 'varchar(100)',
|
434
|
+
'用户年龄': 'varchar(100)',
|
435
|
+
'人群分类': 'varchar(100)',
|
436
|
+
}
|
437
|
+
min_date = df['日期'].min()
|
438
|
+
max_date = df['日期'].max()
|
439
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
440
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
441
|
+
m_engine.df_to_mysql(
|
442
|
+
df=df,
|
443
|
+
db_name=db_name,
|
444
|
+
table_name=table_name,
|
445
|
+
icm_update=['日期', '推广渠道', '营销场景', '商品id', '花费', '人群名字'], # 增量更新, 在聚合数据中使用,其他不要用
|
446
|
+
move_insert=False, # 先删除,再插入
|
447
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
448
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
449
|
+
count=None,
|
450
|
+
filename=None, # 用来追踪处理进度
|
451
|
+
reset_id=False, # 是否重置自增列
|
452
|
+
set_typ=set_typ,
|
453
|
+
)
|
454
|
+
return True
|
200
455
|
|
201
456
|
@try_except
|
202
|
-
def tg_gjc(self):
|
457
|
+
def tg_gjc(self, db_name='聚合数据', table_name='天猫_关键词报表', is_maximize=True):
|
203
458
|
start_date, end_date = self.months_data(num=self.months)
|
204
459
|
projection = {
|
205
460
|
'日期': 1,
|
@@ -224,10 +479,111 @@ class MysqlDatasQuery:
|
|
224
479
|
end_date=end_date,
|
225
480
|
projection=projection,
|
226
481
|
)
|
227
|
-
|
482
|
+
df.rename(columns={
|
483
|
+
'场景名字': '营销场景',
|
484
|
+
'宝贝id': '商品id',
|
485
|
+
'总购物车数': '加购量',
|
486
|
+
'总成交笔数': '成交笔数',
|
487
|
+
'总成交金额': '成交金额'
|
488
|
+
}, inplace=True)
|
489
|
+
df.fillna(0, inplace=True)
|
490
|
+
df = df.astype({
|
491
|
+
'商品id': str,
|
492
|
+
'花费': float,
|
493
|
+
'展现量': int,
|
494
|
+
'点击量': int,
|
495
|
+
'加购量': int,
|
496
|
+
'成交笔数': int,
|
497
|
+
'成交金额': float,
|
498
|
+
'直接成交笔数': int,
|
499
|
+
'直接成交金额': float,
|
500
|
+
}, errors='raise')
|
501
|
+
if is_maximize:
|
502
|
+
df = df.groupby(
|
503
|
+
['日期', '店铺名称', '营销场景', '商品id', '词类型', '词名字_词包名字', '花费', '展现量', '点击量'],
|
504
|
+
as_index=False).agg(
|
505
|
+
**{'加购量': ('加购量', np.max),
|
506
|
+
'成交笔数': ('成交笔数', np.max),
|
507
|
+
'成交金额': ('成交金额', np.max),
|
508
|
+
'直接成交笔数': ('直接成交笔数', np.max),
|
509
|
+
'直接成交金额': ('直接成交金额', np.max)
|
510
|
+
}
|
511
|
+
)
|
512
|
+
else:
|
513
|
+
df = df.groupby(
|
514
|
+
['日期', '店铺名称', '营销场景', '商品id', '词类型', '词名字_词包名字', '花费', '展现量', '点击量'],
|
515
|
+
as_index=False).agg(
|
516
|
+
**{
|
517
|
+
'加购量': ('加购量', np.min),
|
518
|
+
'成交笔数': ('成交笔数', np.min),
|
519
|
+
'成交金额': ('成交金额', np.min),
|
520
|
+
'直接成交笔数': ('直接成交笔数', np.max),
|
521
|
+
'直接成交金额': ('直接成交金额', np.max)
|
522
|
+
}
|
523
|
+
)
|
524
|
+
df.insert(loc=1, column='推广渠道', value='万相台无界版') # df中插入新列
|
525
|
+
df['是否品牌词'] = df['词名字_词包名字'].str.contains('万里马|wanlima', regex=True)
|
526
|
+
df['是否品牌词'] = df['是否品牌词'].apply(lambda x: '品牌词' if x else '')
|
527
|
+
dir_file = f'\\\\192.168.1.198\\时尚事业部\\01.运营部\\0-电商周报-每周五更新\\分类配置文件.xlsx'
|
528
|
+
dir_file2 = '/Volumes/时尚事业部/01.运营部/0-电商周报-每周五更新/分类配置文件.xlsx'
|
529
|
+
if not os.path.isfile(dir_file):
|
530
|
+
dir_file = dir_file2
|
531
|
+
if os.path.isfile(dir_file):
|
532
|
+
df_fl = pd.read_excel(dir_file, sheet_name='关键词分类', header=0)
|
533
|
+
# df_fl.rename(columns={'分类1': '词分类'}, inplace=True)
|
534
|
+
df_fl = df_fl[['关键词', '词分类']]
|
535
|
+
# 合并并获取词分类信息
|
536
|
+
df = pd.merge(df, df_fl, left_on=['词名字_词包名字'], right_on=['关键词'], how='left')
|
537
|
+
df.pop('关键词')
|
538
|
+
df['词分类'].fillna('', inplace=True)
|
539
|
+
if '词分类' in df.columns.tolist():
|
540
|
+
# 这行决定了,从文件中读取的词分类信息优先级高于 ret_keyword 函数的词分类
|
541
|
+
df['词分类'] = df.apply(
|
542
|
+
lambda x: self.ret_keyword(keyword=str(x['词名字_词包名字']), as_file=False) if x['词分类'] == ''
|
543
|
+
else x['词分类'], axis=1
|
544
|
+
)
|
545
|
+
else:
|
546
|
+
df['词分类'] = df['词名字_词包名字'].apply(lambda x: self.ret_keyword(keyword=str(x), as_file=False))
|
547
|
+
set_typ = {
|
548
|
+
'日期': 'date',
|
549
|
+
'推广渠道': 'varchar(100)',
|
550
|
+
'店铺名称': 'varchar(100)',
|
551
|
+
'营销场景': 'varchar(100)',
|
552
|
+
'商品id': 'bigint',
|
553
|
+
'词类型': 'varchar(100)',
|
554
|
+
'词名字_词包名字': 'varchar(255)',
|
555
|
+
'花费': 'decimal(10,2)',
|
556
|
+
'展现量': 'int',
|
557
|
+
'点击量': 'int',
|
558
|
+
'加购量': 'int',
|
559
|
+
'成交笔数': 'int',
|
560
|
+
'成交金额': 'decimal(12,2)',
|
561
|
+
'直接成交笔数': 'int',
|
562
|
+
'直接成交金额': 'decimal(12,2)',
|
563
|
+
'是否品牌词': 'varchar(100)',
|
564
|
+
'词分类': 'varchar(100)',
|
565
|
+
}
|
566
|
+
min_date = df['日期'].min()
|
567
|
+
max_date = df['日期'].max()
|
568
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
569
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
570
|
+
m_engine.df_to_mysql(
|
571
|
+
df=df,
|
572
|
+
db_name=db_name,
|
573
|
+
table_name=table_name,
|
574
|
+
icm_update=['日期', '推广渠道', '营销场景', '商品id', '花费', '词类型', '词名字_词包名字',], # 增量更新, 在聚合数据中使用,其他不要用
|
575
|
+
move_insert=False, # 先删除,再插入
|
576
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
577
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
578
|
+
count=None,
|
579
|
+
filename=None, # 用来追踪处理进度
|
580
|
+
reset_id=False, # 是否重置自增列
|
581
|
+
set_typ=set_typ,
|
582
|
+
)
|
583
|
+
return True
|
228
584
|
|
229
585
|
@try_except
|
230
|
-
def tg_cjzb(self):
|
586
|
+
def tg_cjzb(self, db_name='聚合数据', table_name='天猫_超级直播', is_maximize=True):
|
231
587
|
start_date, end_date = self.months_data(num=self.months)
|
232
588
|
projection = {
|
233
589
|
'日期': 1,
|
@@ -253,10 +609,99 @@ class MysqlDatasQuery:
|
|
253
609
|
end_date=end_date,
|
254
610
|
projection=projection,
|
255
611
|
)
|
256
|
-
|
612
|
+
df.rename(columns={
|
613
|
+
'观看次数': '观看次数',
|
614
|
+
'总购物车数': '加购量',
|
615
|
+
'总成交笔数': '成交笔数',
|
616
|
+
'总成交金额': '成交金额',
|
617
|
+
'场景名字': '营销场景',
|
618
|
+
}, inplace=True)
|
619
|
+
df['营销场景'] = '超级直播'
|
620
|
+
df.fillna(0, inplace=True)
|
621
|
+
df = df.astype({
|
622
|
+
'花费': float,
|
623
|
+
# '点击量': int,
|
624
|
+
'加购量': int,
|
625
|
+
'成交笔数': int,
|
626
|
+
'成交金额': float,
|
627
|
+
'进店量': int,
|
628
|
+
'粉丝关注量': int,
|
629
|
+
'观看次数': int,
|
630
|
+
}, errors='raise')
|
631
|
+
if is_maximize:
|
632
|
+
df = df.groupby(['日期', '店铺名称', '营销场景', '人群名字', '计划名字', '花费', '观看次数', '展现量'],
|
633
|
+
as_index=False).agg(
|
634
|
+
**{
|
635
|
+
'进店量': ('进店量', np.max),
|
636
|
+
'粉丝关注量': ('粉丝关注量', np.max),
|
637
|
+
'加购量': ('加购量', np.max),
|
638
|
+
'成交笔数': ('成交笔数', np.max),
|
639
|
+
'成交金额': ('成交金额', np.max),
|
640
|
+
'直接成交笔数': ('直接成交笔数', np.max),
|
641
|
+
'直接成交金额': ('直接成交金额', np.max),
|
642
|
+
}
|
643
|
+
)
|
644
|
+
else:
|
645
|
+
df = df.groupby(['日期', '店铺名称', '营销场景', '人群名字', '计划名字', '花费', '观看次数', '展现量'],
|
646
|
+
as_index=False).agg(
|
647
|
+
**{
|
648
|
+
'进店量': ('进店量', np.min),
|
649
|
+
'粉丝关注量': ('粉丝关注量', np.min),
|
650
|
+
'加购量': ('加购量', np.min),
|
651
|
+
'成交笔数': ('成交笔数', np.min),
|
652
|
+
'成交金额': ('成交金额', np.min),
|
653
|
+
'直接成交笔数': ('直接成交笔数', np.min),
|
654
|
+
'直接成交金额': ('直接成交金额', np.min),
|
655
|
+
}
|
656
|
+
)
|
657
|
+
df.insert(loc=1, column='推广渠道', value='万相台无界版') # df中插入新列
|
658
|
+
self.pf_datas.append(
|
659
|
+
{
|
660
|
+
'集合名称': table_name,
|
661
|
+
'数据主体': df[['日期', '店铺名称', '推广渠道', '营销场景', '花费', '展现量', '观看次数', '加购量', '成交笔数', '成交金额', '直接成交笔数', '直接成交金额']]
|
662
|
+
},
|
663
|
+
) # 制作其他聚合表
|
664
|
+
if not self.update_service:
|
665
|
+
return
|
666
|
+
set_typ = {
|
667
|
+
'日期': 'date',
|
668
|
+
'推广渠道': 'varchar(100)',
|
669
|
+
'店铺名称': 'varchar(100)',
|
670
|
+
'营销场景': 'varchar(100)',
|
671
|
+
'人群名字': 'varchar(255)',
|
672
|
+
'计划名字': 'varchar(255)',
|
673
|
+
'花费': 'decimal(10,2)',
|
674
|
+
'观看次数': 'int',
|
675
|
+
'展现量': 'int',
|
676
|
+
'进店量': 'int',
|
677
|
+
'粉丝关注量': 'int',
|
678
|
+
'加购量': 'int',
|
679
|
+
'成交笔数': 'int',
|
680
|
+
'成交金额': 'decimal(12,2)',
|
681
|
+
'直接成交笔数': 'int',
|
682
|
+
'直接成交金额': 'decimal(12,2)',
|
683
|
+
}
|
684
|
+
min_date = df['日期'].min()
|
685
|
+
max_date = df['日期'].max()
|
686
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
687
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
688
|
+
m_engine.df_to_mysql(
|
689
|
+
df=df,
|
690
|
+
db_name=db_name,
|
691
|
+
table_name=table_name,
|
692
|
+
icm_update=['日期', '推广渠道', '营销场景', '花费'], # 增量更新, 在聚合数据中使用,其他不要用
|
693
|
+
move_insert=False, # 先删除,再插入
|
694
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
695
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
696
|
+
count=None,
|
697
|
+
filename=None, # 用来追踪处理进度
|
698
|
+
reset_id=False, # 是否重置自增列
|
699
|
+
set_typ=set_typ,
|
700
|
+
)
|
701
|
+
return True
|
257
702
|
|
258
703
|
@try_except
|
259
|
-
def pxb_zh(self):
|
704
|
+
def pxb_zh(self, db_name='聚合数据', table_name='天猫_品销宝账户报表', is_maximize=True):
|
260
705
|
start_date, end_date = self.months_data(num=self.months)
|
261
706
|
projection = {
|
262
707
|
'日期': 1,
|
@@ -280,10 +725,90 @@ class MysqlDatasQuery:
|
|
280
725
|
end_date=end_date,
|
281
726
|
projection=projection,
|
282
727
|
)
|
283
|
-
|
728
|
+
df = df[df['报表类型'] == '账户']
|
729
|
+
df.fillna(value=0, inplace=True)
|
730
|
+
df.rename(columns={
|
731
|
+
'消耗': '花费',
|
732
|
+
'宝贝加购数': '加购量',
|
733
|
+
'搜索量': '品牌搜索量',
|
734
|
+
'搜索访客数': '品牌搜索人数'
|
735
|
+
}, inplace=True)
|
736
|
+
df = df.astype({
|
737
|
+
'花费': float,
|
738
|
+
'展现量': int,
|
739
|
+
'点击量': int,
|
740
|
+
'加购量': int,
|
741
|
+
'成交笔数': int,
|
742
|
+
'成交金额': float,
|
743
|
+
'品牌搜索量': int,
|
744
|
+
'品牌搜索人数': int,
|
745
|
+
}, errors='raise')
|
746
|
+
if is_maximize:
|
747
|
+
df = df.groupby(['日期', '店铺名称', '报表类型', '花费', '展现量', '点击量'], as_index=False).agg(
|
748
|
+
**{
|
749
|
+
'加购量': ('加购量', np.max),
|
750
|
+
'成交笔数': ('成交笔数', np.max),
|
751
|
+
'成交金额': ('成交金额', np.max),
|
752
|
+
'品牌搜索量': ('品牌搜索量', np.max),
|
753
|
+
'品牌搜索人数': ('品牌搜索人数', np.max),
|
754
|
+
}
|
755
|
+
)
|
756
|
+
else:
|
757
|
+
df = df.groupby(['日期', '店铺名称', '报表类型', '花费', '展现量', '点击量'], as_index=False).agg(
|
758
|
+
**{
|
759
|
+
'加购量': ('加购量', np.min),
|
760
|
+
'成交笔数': ('成交笔数', np.min),
|
761
|
+
'成交金额': ('成交金额', np.min),
|
762
|
+
'品牌搜索量': ('品牌搜索量', np.min),
|
763
|
+
'品牌搜索人数': ('品牌搜索人数', np.min),
|
764
|
+
}
|
765
|
+
)
|
766
|
+
df.insert(loc=1, column='推广渠道', value='品销宝') # df中插入新列
|
767
|
+
df.insert(loc=2, column='营销场景', value='品销宝') # df中插入新列
|
768
|
+
self.pf_datas.append(
|
769
|
+
{
|
770
|
+
'集合名称': table_name,
|
771
|
+
'数据主体': df[['日期', '店铺名称', '推广渠道', '营销场景', '花费', '展现量', '点击量', '加购量', '成交笔数', '成交金额']]
|
772
|
+
},
|
773
|
+
) # 制作其他聚合表
|
774
|
+
if not self.update_service:
|
775
|
+
return
|
776
|
+
set_typ = {
|
777
|
+
'日期': 'date',
|
778
|
+
'推广渠道': 'varchar(100)',
|
779
|
+
'店铺名称': 'varchar(100)',
|
780
|
+
'营销场景': 'varchar(100)',
|
781
|
+
'报表类型': 'varchar(100)',
|
782
|
+
'花费': 'decimal(10,2)',
|
783
|
+
'展现量': 'int',
|
784
|
+
'点击量': 'int',
|
785
|
+
'加购量': 'int',
|
786
|
+
'成交笔数': 'int',
|
787
|
+
'成交金额': 'decimal(12,2)',
|
788
|
+
'品牌搜索量': 'int',
|
789
|
+
'品牌搜索人数': 'int',
|
790
|
+
}
|
791
|
+
min_date = df['日期'].min()
|
792
|
+
max_date = df['日期'].max()
|
793
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
794
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
795
|
+
m_engine.df_to_mysql(
|
796
|
+
df=df,
|
797
|
+
db_name=db_name,
|
798
|
+
table_name=table_name,
|
799
|
+
icm_update=['日期', '报表类型', '推广渠道', '营销场景', '花费'], # 增量更新, 在聚合数据中使用,其他不要用
|
800
|
+
move_insert=False, # 先删除,再插入
|
801
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
802
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
803
|
+
count=None,
|
804
|
+
filename=None, # 用来追踪处理进度
|
805
|
+
reset_id=False, # 是否重置自增列
|
806
|
+
set_typ=set_typ,
|
807
|
+
)
|
808
|
+
return True
|
284
809
|
|
285
810
|
@try_except
|
286
|
-
def idbm(self):
|
811
|
+
def idbm(self, db_name='聚合数据', table_name='商品id编码表'):
|
287
812
|
""" 用生意经日数据制作商品 id 和编码对照表 """
|
288
813
|
data_values = self.download.columns_to_list(
|
289
814
|
db_name='生意经3',
|
@@ -291,10 +816,53 @@ class MysqlDatasQuery:
|
|
291
816
|
columns_name=['宝贝id', '商家编码', '行业类目'],
|
292
817
|
)
|
293
818
|
df = pd.DataFrame(data=data_values)
|
294
|
-
|
819
|
+
df['宝贝id'] = df['宝贝id'].astype(str)
|
820
|
+
df.drop_duplicates(subset='宝贝id', keep='last', inplace=True, ignore_index=True)
|
821
|
+
# df['行业类目'] = df['行业类目'].apply(lambda x: re.sub(' ', '', x))
|
822
|
+
try:
|
823
|
+
df[['一级类目', '二级类目', '三级类目']] = df['行业类目'].str.split(' -> ', expand=True).loc[:, 0:2]
|
824
|
+
except:
|
825
|
+
try:
|
826
|
+
df[['一级类目', '二级类目']] = df['行业类目'].str.split(' -> ', expand=True).loc[:, 0:1]
|
827
|
+
except:
|
828
|
+
df['一级类目'] = df['行业类目']
|
829
|
+
df.drop('行业类目', axis=1, inplace=True)
|
830
|
+
df.sort_values('宝贝id', ascending=False, inplace=True)
|
831
|
+
df = df[(df['宝贝id'] != '973') & (df['宝贝id'] != '973')]
|
832
|
+
set_typ = {
|
833
|
+
'宝贝id': 'bigint',
|
834
|
+
'商家编码': 'varchar(100)',
|
835
|
+
'一级类目': 'varchar(100)',
|
836
|
+
'二级类目': 'varchar(100)',
|
837
|
+
'三级类目': 'varchar(100)',
|
838
|
+
}
|
839
|
+
self.pf_datas.append(
|
840
|
+
{
|
841
|
+
'集合名称': table_name,
|
842
|
+
'数据主体': df[['宝贝id', '商家编码']]
|
843
|
+
}
|
844
|
+
) # 制作其他聚合表
|
845
|
+
if not self.update_service:
|
846
|
+
return
|
847
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
848
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name}')
|
849
|
+
m_engine.df_to_mysql(
|
850
|
+
df=df,
|
851
|
+
db_name=db_name,
|
852
|
+
table_name=table_name,
|
853
|
+
icm_update=['宝贝id'], # 增量更新, 在聚合数据中使用,其他不要用
|
854
|
+
move_insert=False, # 先删除,再插入
|
855
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
856
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
857
|
+
count=None,
|
858
|
+
filename=None, # 用来追踪处理进度
|
859
|
+
reset_id=False, # 是否重置自增列
|
860
|
+
set_typ=set_typ,
|
861
|
+
)
|
862
|
+
return True
|
295
863
|
|
296
864
|
@try_except
|
297
|
-
def sp_picture(self):
|
865
|
+
def sp_picture(self, db_name='聚合数据', table_name='商品id图片对照表'):
|
298
866
|
""" 用生意经日数据制作商品 id 和编码对照表 """
|
299
867
|
data_values = self.download.columns_to_list(
|
300
868
|
db_name='属性设置3',
|
@@ -302,10 +870,56 @@ class MysqlDatasQuery:
|
|
302
870
|
columns_name=['日期', '商品id', '商品白底图', '方版场景图'],
|
303
871
|
)
|
304
872
|
df = pd.DataFrame(data=data_values)
|
305
|
-
|
873
|
+
df['商品id'] = df['商品id'].astype('int64')
|
874
|
+
df['日期'] = df['日期'].astype('datetime64[ns]')
|
875
|
+
df = df[(df['商品白底图'] != '0') | (df['方版场景图'] != '0')]
|
876
|
+
# 白底图优先
|
877
|
+
df['商品图片'] = df[['商品白底图', '方版场景图']].apply(
|
878
|
+
lambda x: x['商品白底图'] if x['商品白底图'] != '0' else x['方版场景图'], axis=1)
|
879
|
+
# # 方版场景图优先
|
880
|
+
# df['商品图片'] = df[['商品白底图', '方版场景图']].apply(
|
881
|
+
# lambda x: x['方版场景图'] if x['方版场景图'] != '0' else x['商品白底图'], axis=1)
|
882
|
+
df.sort_values(by=['商品id', '日期'], ascending=[False, True], ignore_index=True, inplace=True)
|
883
|
+
df.drop_duplicates(subset=['商品id'], keep='last', inplace=True, ignore_index=True)
|
884
|
+
df = df[['商品id', '商品图片', '日期']]
|
885
|
+
df['商品图片'] = df['商品图片'].apply(lambda x: x if 'http' in x else None) # 检查是否是 http 链接
|
886
|
+
df.dropna(how='all', subset=['商品图片'], axis=0, inplace=True) # 删除指定列含有空值的行
|
887
|
+
df['商品链接'] = df['商品id'].apply(
|
888
|
+
lambda x: f'https://detail.tmall.com/item.htm?id={str(x)}' if x and '.com' not in str(x) else x)
|
889
|
+
df.sort_values(by='商品id', ascending=False, ignore_index=True, inplace=True) # ascending=False 降序排列
|
890
|
+
set_typ = {
|
891
|
+
'商品id': 'bigint',
|
892
|
+
'商品图片': 'varchar(255)',
|
893
|
+
'日期': 'date',
|
894
|
+
'商品链接': 'varchar(255)',
|
895
|
+
}
|
896
|
+
self.pf_datas.append(
|
897
|
+
{
|
898
|
+
'集合名称': table_name,
|
899
|
+
'数据主体': df[['商品id', '商品图片']]
|
900
|
+
}
|
901
|
+
) # 制作其他聚合表
|
902
|
+
if not self.update_service:
|
903
|
+
return
|
904
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
905
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name}')
|
906
|
+
m_engine.df_to_mysql(
|
907
|
+
df=df,
|
908
|
+
db_name=db_name,
|
909
|
+
table_name=table_name,
|
910
|
+
icm_update=['商品id'], # 增量更新, 在聚合数据中使用,其他不要用
|
911
|
+
move_insert=False, # 先删除,再插入
|
912
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
913
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
914
|
+
count=None,
|
915
|
+
filename=None, # 用来追踪处理进度
|
916
|
+
reset_id=False, # 是否重置自增列
|
917
|
+
set_typ=set_typ,
|
918
|
+
)
|
919
|
+
return True
|
306
920
|
|
307
921
|
@try_except
|
308
|
-
def dplyd(self):
|
922
|
+
def dplyd(self, db_name='聚合数据', table_name='店铺流量来源构成'):
|
309
923
|
""" 新旧版取的字段是一样的 """
|
310
924
|
start_date, end_date = self.months_data(num=self.months)
|
311
925
|
projection = {
|
@@ -327,34 +941,66 @@ class MysqlDatasQuery:
|
|
327
941
|
end_date=end_date,
|
328
942
|
projection=projection,
|
329
943
|
)
|
330
|
-
#
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
944
|
+
# 包含三级来源名称和预设索引值列
|
945
|
+
# 截取 从上月1日 至 今天的花费数据, 推广款式按此数据从高到低排序(商品图+排序)
|
946
|
+
df_visitor3 = df.groupby(['日期', '三级来源'], as_index=False).agg({'访客数': 'sum'})
|
947
|
+
df_visitor3 = df_visitor3[~df_visitor3['三级来源'].isin([''])] # 指定列中删除包含空值的行
|
948
|
+
# df_visitor = df_visitor[(df_visitor['日期'] >= f'{year_my}-{last_month.month}-01')]
|
949
|
+
df_visitor3 = df_visitor3.groupby(['三级来源'], as_index=False).agg({'访客数': 'sum'})
|
950
|
+
df_visitor3.sort_values('访客数', ascending=False, ignore_index=True, inplace=True)
|
951
|
+
df_visitor3.reset_index(inplace=True)
|
952
|
+
df_visitor3['index'] = df_visitor3['index'] + 100
|
953
|
+
df_visitor3.rename(columns={'index': '三级访客索引'}, inplace=True)
|
954
|
+
df_visitor3 = df_visitor3[['三级来源', '三级访客索引']]
|
955
|
+
|
956
|
+
# 包含二级来源名称和预设索引值列
|
957
|
+
df_visitor2 = df.groupby(['日期', '二级来源'], as_index=False).agg({'访客数': 'sum'})
|
958
|
+
df_visitor2 = df_visitor2[~df_visitor2['二级来源'].isin([''])] # 指定列中删除包含空值的行
|
959
|
+
# df_visitor2 = df_visitor2[(df_visitor2['日期'] >= f'{year_my}-{last_month.month}-01')]
|
960
|
+
df_visitor2 = df_visitor2.groupby(['二级来源'], as_index=False).agg({'访客数': 'sum'})
|
961
|
+
df_visitor2.sort_values('访客数', ascending=False, ignore_index=True, inplace=True)
|
962
|
+
df_visitor2.reset_index(inplace=True)
|
963
|
+
df_visitor2['index'] = df_visitor2['index'] + 100
|
964
|
+
df_visitor2.rename(columns={'index': '二级访客索引'}, inplace=True)
|
965
|
+
df_visitor2 = df_visitor2[['二级来源', '二级访客索引']]
|
966
|
+
|
967
|
+
df = pd.merge(df, df_visitor2, how='left', left_on='二级来源', right_on='二级来源')
|
968
|
+
df = pd.merge(df, df_visitor3, how='left', left_on='三级来源', right_on='三级来源')
|
969
|
+
set_typ = {
|
970
|
+
'日期': 'date',
|
971
|
+
'一级来源': 'varchar(100)',
|
972
|
+
'二级来源': 'varchar(100)',
|
973
|
+
'三级来源': 'varchar(100)',
|
974
|
+
'访客数': 'int',
|
975
|
+
'支付金额': 'decimal(12,2)',
|
976
|
+
'支付买家数': 'int',
|
977
|
+
'支付转化率': 'decimal(10,4)',
|
978
|
+
'加购人数': 'int',
|
979
|
+
'店铺名称': 'varchar(100)',
|
980
|
+
'二级访客索引': 'smallint',
|
981
|
+
'三级访客索引': 'smallint',
|
346
982
|
}
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
983
|
+
min_date = df['日期'].min()
|
984
|
+
max_date = df['日期'].max()
|
985
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
986
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
987
|
+
m_engine.df_to_mysql(
|
988
|
+
df=df,
|
989
|
+
db_name=db_name,
|
990
|
+
table_name=table_name,
|
991
|
+
icm_update=['日期', '一级来源', '二级来源', '三级来源', '访客数'], # 增量更新, 在聚合数据中使用,其他不要用
|
992
|
+
move_insert=False, # 先删除,再插入
|
993
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
994
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
995
|
+
count=None,
|
996
|
+
filename=None, # 用来追踪处理进度
|
997
|
+
reset_id=False, # 是否重置自增列
|
998
|
+
set_typ=set_typ,
|
353
999
|
)
|
354
|
-
return
|
1000
|
+
return True
|
355
1001
|
|
356
1002
|
@try_except
|
357
|
-
def sp_cost(self):
|
1003
|
+
def sp_cost(self, db_name='聚合数据', table_name='商品成本'):
|
358
1004
|
""" 电商定价 """
|
359
1005
|
data_values = self.download.columns_to_list(
|
360
1006
|
db_name='属性设置3',
|
@@ -362,10 +1008,46 @@ class MysqlDatasQuery:
|
|
362
1008
|
columns_name=['日期', '款号', '年份季节', '吊牌价', '商家平台', '成本价', '天猫页面价', '天猫中促价'],
|
363
1009
|
)
|
364
1010
|
df = pd.DataFrame(data=data_values)
|
365
|
-
|
1011
|
+
df.sort_values(by=['款号', '日期'], ascending=[False, True], ignore_index=True, inplace=True)
|
1012
|
+
df.drop_duplicates(subset=['款号'], keep='last', inplace=True, ignore_index=True)
|
1013
|
+
set_typ = {
|
1014
|
+
'日期': 'date',
|
1015
|
+
'款号': 'varchar(100)',
|
1016
|
+
'年份季节': 'varchar(100)',
|
1017
|
+
'吊牌价': 'decimal(10,2)',
|
1018
|
+
'成本价': 'decimal(10,2)',
|
1019
|
+
'天猫页面价': 'decimal(10,2)',
|
1020
|
+
'天猫中促价': 'decimal(10,2)',
|
1021
|
+
}
|
1022
|
+
self.pf_datas.append(
|
1023
|
+
{
|
1024
|
+
'集合名称': table_name,
|
1025
|
+
'数据主体': df[['款号', '成本价']]
|
1026
|
+
}
|
1027
|
+
) # 制作其他聚合表
|
1028
|
+
if not self.update_service:
|
1029
|
+
return
|
1030
|
+
min_date = df['日期'].min()
|
1031
|
+
max_date = df['日期'].max()
|
1032
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
1033
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
1034
|
+
m_engine.df_to_mysql(
|
1035
|
+
df=df,
|
1036
|
+
db_name=db_name,
|
1037
|
+
table_name=table_name,
|
1038
|
+
icm_update=['款号'], # 增量更新, 在聚合数据中使用,其他不要用
|
1039
|
+
move_insert=False, # 先删除,再插入
|
1040
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
1041
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
1042
|
+
count=None,
|
1043
|
+
filename=None, # 用来追踪处理进度
|
1044
|
+
reset_id=False, # 是否重置自增列
|
1045
|
+
set_typ=set_typ,
|
1046
|
+
)
|
1047
|
+
return True
|
366
1048
|
|
367
1049
|
@try_except
|
368
|
-
def jdjzt(self):
|
1050
|
+
def jdjzt(self, db_name='聚合数据', table_name='京东_京准通'):
|
369
1051
|
start_date, end_date = self.months_data(num=self.months)
|
370
1052
|
projection = {
|
371
1053
|
'日期': 1,
|
@@ -391,13 +1073,68 @@ class MysqlDatasQuery:
|
|
391
1073
|
end_date=end_date,
|
392
1074
|
projection=projection,
|
393
1075
|
)
|
394
|
-
|
1076
|
+
df = df.groupby(
|
1077
|
+
['日期', '店铺名称', '产品线', '触发sku_id', '跟单sku_id', 'spu_id', '花费', '展现数', '点击数'],
|
1078
|
+
as_index=False).agg(
|
1079
|
+
**{'直接订单行': ('直接订单行', np.max),
|
1080
|
+
'直接订单金额': ('直接订单金额', np.max),
|
1081
|
+
'总订单行': ('总订单行', np.max),
|
1082
|
+
'总订单金额': ('总订单金额', np.max),
|
1083
|
+
'直接加购数': ('直接加购数', np.max),
|
1084
|
+
'总加购数': ('总加购数', np.max),
|
1085
|
+
}
|
1086
|
+
)
|
1087
|
+
df = df[df['花费'] > 0]
|
1088
|
+
self.pf_datas_jd.append(
|
1089
|
+
{
|
1090
|
+
'集合名称': table_name,
|
1091
|
+
'数据主体': df[['日期', '产品线', '触发sku_id', '跟单sku_id', '花费']]
|
1092
|
+
}
|
1093
|
+
) # 制作其他聚合表
|
1094
|
+
if not self.update_service:
|
1095
|
+
return
|
1096
|
+
set_typ = {
|
1097
|
+
'日期': 'date',
|
1098
|
+
'店铺名称': 'varchar(100)',
|
1099
|
+
'产品线': 'varchar(100)',
|
1100
|
+
'触发sku_id': 'bigint',
|
1101
|
+
'跟单sku_id': 'bigint',
|
1102
|
+
'spu_id': 'bigint',
|
1103
|
+
'花费': 'decimal(10,2)',
|
1104
|
+
'展现数': 'int',
|
1105
|
+
'点击数': 'int',
|
1106
|
+
'直接订单行': 'int',
|
1107
|
+
'直接订单金额': 'decimal(10,2)',
|
1108
|
+
'总订单行': 'int',
|
1109
|
+
'总订单金额': 'decimal(10,2)',
|
1110
|
+
'直接加购数': 'int',
|
1111
|
+
'总加购数': 'int',
|
1112
|
+
}
|
1113
|
+
min_date = df['日期'].min()
|
1114
|
+
max_date = df['日期'].max()
|
1115
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
1116
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
1117
|
+
m_engine.df_to_mysql(
|
1118
|
+
df=df,
|
1119
|
+
db_name=db_name,
|
1120
|
+
table_name=table_name,
|
1121
|
+
icm_update=['日期', '产品线', '触发sku_id', '跟单sku_id', '花费', ], # 增量更新, 在聚合数据中使用,其他不要用
|
1122
|
+
move_insert=False, # 先删除,再插入
|
1123
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
1124
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
1125
|
+
count=None,
|
1126
|
+
filename=None, # 用来追踪处理进度
|
1127
|
+
reset_id=False, # 是否重置自增列
|
1128
|
+
set_typ=set_typ,
|
1129
|
+
)
|
1130
|
+
return True
|
395
1131
|
|
396
1132
|
@try_except
|
397
|
-
def jdqzyx(self):
|
1133
|
+
def jdqzyx(self, db_name='聚合数据', table_name='京东_京准通_全站营销'):
|
398
1134
|
start_date, end_date = self.months_data(num=self.months)
|
399
1135
|
projection = {
|
400
1136
|
'日期': 1,
|
1137
|
+
'店铺名称': 1,
|
401
1138
|
'产品线': 1,
|
402
1139
|
'花费': 1,
|
403
1140
|
'全站投产比': 1,
|
@@ -415,10 +1152,51 @@ class MysqlDatasQuery:
|
|
415
1152
|
end_date=end_date,
|
416
1153
|
projection=projection,
|
417
1154
|
)
|
418
|
-
|
1155
|
+
df = df.groupby(['日期', '店铺名称', '产品线', '花费'], as_index=False).agg(
|
1156
|
+
**{'全站投产比': ('全站投产比', np.max),
|
1157
|
+
'全站交易额': ('全站交易额', np.max),
|
1158
|
+
'全站订单行': ('全站订单行', np.max),
|
1159
|
+
'全站订单成本': ('全站订单成本', np.max),
|
1160
|
+
'全站费比': ('全站费比', np.max),
|
1161
|
+
'核心位置展现量': ('核心位置展现量', np.max),
|
1162
|
+
'核心位置点击量': ('核心位置点击量', np.max),
|
1163
|
+
}
|
1164
|
+
)
|
1165
|
+
df = df[df['花费'] > 0]
|
1166
|
+
set_typ = {
|
1167
|
+
'日期': 'date',
|
1168
|
+
'店铺名称': 'varchar(100)',
|
1169
|
+
'产品线': 'varchar(100)',
|
1170
|
+
'花费': 'decimal(10,2)',
|
1171
|
+
'全站投产比': 'decimal(10,2)',
|
1172
|
+
'全站交易额': 'decimal(10,2)',
|
1173
|
+
'全站订单行': 'decimal(10,2)',
|
1174
|
+
'全站订单成本': 'decimal(10,2)',
|
1175
|
+
'全站费比': 'decimal(8,4)',
|
1176
|
+
'核心位置展现量': 'int',
|
1177
|
+
'核心位置点击量': 'int',
|
1178
|
+
}
|
1179
|
+
min_date = df['日期'].min()
|
1180
|
+
max_date = df['日期'].max()
|
1181
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
1182
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
1183
|
+
m_engine.df_to_mysql(
|
1184
|
+
df=df,
|
1185
|
+
db_name=db_name,
|
1186
|
+
table_name=table_name,
|
1187
|
+
icm_update=['日期', '产品线', '花费'], # 增量更新, 在聚合数据中使用,其他不要用
|
1188
|
+
move_insert=False, # 先删除,再插入
|
1189
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
1190
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
1191
|
+
count=None,
|
1192
|
+
filename=None, # 用来追踪处理进度
|
1193
|
+
reset_id=False, # 是否重置自增列
|
1194
|
+
set_typ=set_typ,
|
1195
|
+
)
|
1196
|
+
return True
|
419
1197
|
|
420
1198
|
@try_except
|
421
|
-
def jd_gjc(self):
|
1199
|
+
def jd_gjc(self, db_name='聚合数据', table_name='京东_关键词报表'):
|
422
1200
|
start_date, end_date = self.months_data(num=self.months)
|
423
1201
|
projection = {
|
424
1202
|
'日期': 1,
|
@@ -449,13 +1227,77 @@ class MysqlDatasQuery:
|
|
449
1227
|
end_date=end_date,
|
450
1228
|
projection=projection,
|
451
1229
|
)
|
452
|
-
|
1230
|
+
df_lin = df[['计划id', '推广计划']]
|
1231
|
+
df_lin.drop_duplicates(subset=['计划id'], keep='last', inplace=True, ignore_index=True)
|
1232
|
+
df = df.groupby(
|
1233
|
+
['日期', '产品线', '计划类型', '计划id', '搜索词', '关键词', '关键词购买类型', '广告定向类型', '展现数',
|
1234
|
+
'点击数', '花费'],
|
1235
|
+
as_index=False).agg(
|
1236
|
+
**{
|
1237
|
+
'直接订单行': ('直接订单行', np.max),
|
1238
|
+
'直接订单金额': ('直接订单金额', np.max),
|
1239
|
+
'总订单行': ('总订单行', np.max),
|
1240
|
+
'总订单金额': ('总订单金额', np.max),
|
1241
|
+
'总加购数': ('总加购数', np.max),
|
1242
|
+
'领券数': ('领券数', np.max),
|
1243
|
+
'商品关注数': ('商品关注数', np.max),
|
1244
|
+
'店铺关注数': ('店铺关注数', np.max)
|
1245
|
+
}
|
1246
|
+
)
|
1247
|
+
df = pd.merge(df, df_lin, how='left', left_on='计划id', right_on='计划id')
|
1248
|
+
df['k_是否品牌词'] = df['关键词'].str.contains('万里马|wanlima', regex=True)
|
1249
|
+
df['k_是否品牌词'] = df['k_是否品牌词'].apply(lambda x: '品牌词' if x else '')
|
1250
|
+
df['s_是否品牌词'] = df['搜索词'].str.contains('万里马|wanlima', regex=True)
|
1251
|
+
df['s_是否品牌词'] = df['s_是否品牌词'].apply(lambda x: '品牌词' if x else '')
|
1252
|
+
set_typ = {
|
1253
|
+
'日期': 'date',
|
1254
|
+
'产品线': 'varchar(100)',
|
1255
|
+
'计划类型': 'varchar(100)',
|
1256
|
+
'计划id': 'varchar(100)',
|
1257
|
+
'搜索词': 'varchar(100)',
|
1258
|
+
'关键词': 'varchar(100)',
|
1259
|
+
'关键词购买类型': 'varchar(100)',
|
1260
|
+
'广告定向类型': 'varchar(100)',
|
1261
|
+
'展现数': 'int',
|
1262
|
+
'点击数': 'int',
|
1263
|
+
'花费': 'decimal(10,2)',
|
1264
|
+
'直接订单行': 'int',
|
1265
|
+
'直接订单金额': 'decimal(12,2)',
|
1266
|
+
'总订单行': 'int',
|
1267
|
+
'总订单金额': 'decimal(12,2)',
|
1268
|
+
'总加购数': 'int',
|
1269
|
+
'领券数': 'int',
|
1270
|
+
'商品关注数': 'int',
|
1271
|
+
'店铺关注数': 'int',
|
1272
|
+
'推广计划': 'varchar(100)',
|
1273
|
+
'k_是否品牌词': 'varchar(100)',
|
1274
|
+
's_是否品牌词': 'varchar(100)',
|
1275
|
+
}
|
1276
|
+
min_date = df['日期'].min()
|
1277
|
+
max_date = df['日期'].max()
|
1278
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
1279
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
1280
|
+
m_engine.df_to_mysql(
|
1281
|
+
df=df,
|
1282
|
+
db_name=db_name,
|
1283
|
+
table_name=table_name,
|
1284
|
+
icm_update=['日期', '产品线', '搜索词', '关键词', '展现数', '花费'], # 增量更新, 在聚合数据中使用,其他不要用
|
1285
|
+
move_insert=False, # 先删除,再插入
|
1286
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
1287
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
1288
|
+
count=None,
|
1289
|
+
filename=None, # 用来追踪处理进度
|
1290
|
+
reset_id=False, # 是否重置自增列
|
1291
|
+
set_typ=set_typ,
|
1292
|
+
)
|
1293
|
+
return True
|
453
1294
|
|
454
1295
|
@try_except
|
455
|
-
def sku_sales(self):
|
1296
|
+
def sku_sales(self, db_name='聚合数据', table_name='京东_sku_商品明细'):
|
456
1297
|
start_date, end_date = self.months_data(num=self.months)
|
457
1298
|
projection = {
|
458
1299
|
'日期': 1,
|
1300
|
+
'店铺名称': 1,
|
459
1301
|
'商品id': 1,
|
460
1302
|
'货号': 1,
|
461
1303
|
'成交单量': 1,
|
@@ -472,13 +1314,59 @@ class MysqlDatasQuery:
|
|
472
1314
|
end_date=end_date,
|
473
1315
|
projection=projection,
|
474
1316
|
)
|
475
|
-
|
1317
|
+
df = df[df['商品id'] != '合计']
|
1318
|
+
df = df.groupby(['日期', '店铺名称', '商品id', '货号', '访客数', '成交客户数', '加购商品件数', '加购人数'],
|
1319
|
+
as_index=False).agg(
|
1320
|
+
**{
|
1321
|
+
'成交单量': ('成交单量', np.max),
|
1322
|
+
'成交金额': ('成交金额', np.max),
|
1323
|
+
}
|
1324
|
+
)
|
1325
|
+
self.pf_datas_jd.append(
|
1326
|
+
{
|
1327
|
+
'集合名称': table_name,
|
1328
|
+
'数据主体': df
|
1329
|
+
}
|
1330
|
+
) # 制作其他聚合表
|
1331
|
+
if not self.update_service:
|
1332
|
+
return
|
1333
|
+
set_typ = {
|
1334
|
+
'日期': 'date',
|
1335
|
+
'店铺名称': 'varchar(100)',
|
1336
|
+
'商品id': 'varchar(100)',
|
1337
|
+
'货号': 'varchar(100)',
|
1338
|
+
'访客数': 'int',
|
1339
|
+
'成交客户数': 'int',
|
1340
|
+
'加购商品件数': 'int',
|
1341
|
+
'加购人数': 'int',
|
1342
|
+
'成交单量': 'int',
|
1343
|
+
'成交金额': 'decimal(10,2)',
|
1344
|
+
}
|
1345
|
+
min_date = df['日期'].min()
|
1346
|
+
max_date = df['日期'].max()
|
1347
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
1348
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
1349
|
+
m_engine.df_to_mysql(
|
1350
|
+
df=df,
|
1351
|
+
db_name=db_name,
|
1352
|
+
table_name=table_name,
|
1353
|
+
icm_update=['日期', '商品id', '成交单量'], # 增量更新, 在聚合数据中使用,其他不要用
|
1354
|
+
move_insert=False, # 先删除,再插入
|
1355
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
1356
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
1357
|
+
count=None,
|
1358
|
+
filename=None, # 用来追踪处理进度
|
1359
|
+
reset_id=False, # 是否重置自增列
|
1360
|
+
set_typ=set_typ,
|
1361
|
+
)
|
1362
|
+
return True
|
476
1363
|
|
477
1364
|
@try_except
|
478
|
-
def spu_sales(self):
|
1365
|
+
def spu_sales(self, db_name='聚合数据', table_name='京东_spu_商品明细'):
|
479
1366
|
start_date, end_date = self.months_data(num=self.months)
|
480
1367
|
projection = {
|
481
1368
|
'日期': 1,
|
1369
|
+
'店铺名称': 1,
|
482
1370
|
'商品id': 1,
|
483
1371
|
'货号': 1,
|
484
1372
|
'成交单量': 1,
|
@@ -495,7 +1383,44 @@ class MysqlDatasQuery:
|
|
495
1383
|
end_date=end_date,
|
496
1384
|
projection=projection,
|
497
1385
|
)
|
498
|
-
|
1386
|
+
df = df[df['商品id'] != '合计']
|
1387
|
+
df = df.groupby(['日期', '店铺名称', '商品id', '货号', '访客数', '成交客户数', '加购商品件数', '加购人数'],
|
1388
|
+
as_index=False).agg(
|
1389
|
+
**{
|
1390
|
+
'成交单量': ('成交单量', np.max),
|
1391
|
+
'成交金额': ('成交金额', np.max),
|
1392
|
+
}
|
1393
|
+
)
|
1394
|
+
set_typ = {
|
1395
|
+
'日期': 'date',
|
1396
|
+
'店铺名称': 'varchar(100)',
|
1397
|
+
'商品id': 'varchar(100)',
|
1398
|
+
'货号': 'varchar(100)',
|
1399
|
+
'访客数': 'int',
|
1400
|
+
'成交客户数': 'int',
|
1401
|
+
'加购商品件数': 'int',
|
1402
|
+
'加购人数': 'int',
|
1403
|
+
'成交单量': 'int',
|
1404
|
+
'成交金额': 'decimal(10,2)',
|
1405
|
+
}
|
1406
|
+
min_date = df['日期'].min()
|
1407
|
+
max_date = df['日期'].max()
|
1408
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
1409
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
1410
|
+
m_engine.df_to_mysql(
|
1411
|
+
df=df,
|
1412
|
+
db_name=db_name,
|
1413
|
+
table_name=table_name,
|
1414
|
+
icm_update=['日期', '商品id', '成交单量'], # 增量更新, 在聚合数据中使用,其他不要用
|
1415
|
+
move_insert=False, # 先删除,再插入
|
1416
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
1417
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
1418
|
+
count=None,
|
1419
|
+
filename=None, # 用来追踪处理进度
|
1420
|
+
reset_id=False, # 是否重置自增列
|
1421
|
+
set_typ=set_typ,
|
1422
|
+
)
|
1423
|
+
return True
|
499
1424
|
|
500
1425
|
@staticmethod
|
501
1426
|
def months_data(num=0, end_date=None):
|
@@ -507,7 +1432,7 @@ class MysqlDatasQuery:
|
|
507
1432
|
return pd.to_datetime(start_date), pd.to_datetime(end_date)
|
508
1433
|
|
509
1434
|
@try_except
|
510
|
-
def se_search(self):
|
1435
|
+
def se_search(self, db_name='聚合数据', table_name='天猫店铺来源_手淘搜索'):
|
511
1436
|
start_date, end_date = self.months_data(num=self.months)
|
512
1437
|
projection = {
|
513
1438
|
'日期': 1,
|
@@ -531,10 +1456,53 @@ class MysqlDatasQuery:
|
|
531
1456
|
end_date=end_date,
|
532
1457
|
projection=projection,
|
533
1458
|
)
|
534
|
-
|
1459
|
+
df = df.groupby(
|
1460
|
+
['日期', '店铺名称', '词类型', '搜索词'],
|
1461
|
+
as_index=False).agg(
|
1462
|
+
**{
|
1463
|
+
'访客数': ('访客数', np.max),
|
1464
|
+
'加购人数': ('加购人数', np.max),
|
1465
|
+
'支付金额': ('支付金额', np.max),
|
1466
|
+
'支付转化率': ('支付转化率', np.max),
|
1467
|
+
'支付买家数': ('支付买家数', np.max),
|
1468
|
+
'客单价': ('客单价', np.max),
|
1469
|
+
'uv价值': ('uv价值', np.max)
|
1470
|
+
}
|
1471
|
+
)
|
1472
|
+
set_typ = {
|
1473
|
+
'日期': 'date',
|
1474
|
+
'店铺名称': 'varchar(100)',
|
1475
|
+
'词类型': 'varchar(100)',
|
1476
|
+
'搜索词': 'varchar(100)',
|
1477
|
+
'访客数': 'int',
|
1478
|
+
'加购人数': 'int',
|
1479
|
+
'支付金额': 'decimal(10,2)',
|
1480
|
+
'支付转化率': 'decimal(10,4)',
|
1481
|
+
'支付买家数': 'int',
|
1482
|
+
'客单价': 'decimal(10,2)',
|
1483
|
+
'uv价值': 'decimal(10,2)',
|
1484
|
+
}
|
1485
|
+
min_date = df['日期'].min()
|
1486
|
+
max_date = df['日期'].max()
|
1487
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
1488
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
1489
|
+
m_engine.df_to_mysql(
|
1490
|
+
df=df,
|
1491
|
+
db_name=db_name,
|
1492
|
+
table_name=table_name,
|
1493
|
+
icm_update=['日期', '店铺名称', '词类型', '搜索词'], # 增量更新, 在聚合数据中使用,其他不要用
|
1494
|
+
move_insert=False, # 先删除,再插入
|
1495
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
1496
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
1497
|
+
count=None,
|
1498
|
+
filename=None, # 用来追踪处理进度
|
1499
|
+
reset_id=False, # 是否重置自增列
|
1500
|
+
set_typ=set_typ,
|
1501
|
+
)
|
1502
|
+
return True
|
535
1503
|
|
536
1504
|
@try_except
|
537
|
-
def zb_ccfx(self):
|
1505
|
+
def zb_ccfx(self, db_name='聚合数据', table_name='生意参谋_直播场次分析'):
|
538
1506
|
start_date, end_date = self.months_data(num=self.months)
|
539
1507
|
projection = {
|
540
1508
|
# '日期': 1,
|
@@ -577,10 +1545,102 @@ class MysqlDatasQuery:
|
|
577
1545
|
end_date=end_date,
|
578
1546
|
projection=projection,
|
579
1547
|
)
|
580
|
-
|
1548
|
+
df.drop_duplicates(subset=['场次id'], keep='first', inplace=True, ignore_index=True)
|
1549
|
+
set_typ = {
|
1550
|
+
'日期': 'DATE',
|
1551
|
+
'店铺名称': 'varchar(100)',
|
1552
|
+
'fvr_pv': 'int',
|
1553
|
+
'封面图点击率': 'decimal(10,4)',
|
1554
|
+
'itrt_pv ': 'int',
|
1555
|
+
'开播时长': 'smallint',
|
1556
|
+
'成交笔数': 'smallint',
|
1557
|
+
'aov': 'decimal(10,2)',
|
1558
|
+
'退款金额': 'decimal(12,2)',
|
1559
|
+
'曝光pv': 'int',
|
1560
|
+
'场次信息': 'varchar(255)',
|
1561
|
+
'cmt_uv': 'int',
|
1562
|
+
'退款件数占比': 'decimal(10,4)',
|
1563
|
+
'reward_gift_cnt': 'smallint',
|
1564
|
+
'观看人数': 'int',
|
1565
|
+
'开播时长_f': 'varchar(100)',
|
1566
|
+
'reward_uv_rate': 'smallint',
|
1567
|
+
'fvr_uv': 'int',
|
1568
|
+
'直播开播时间': 'datetime',
|
1569
|
+
'商品点击率': 'decimal(10,4)',
|
1570
|
+
'加购次数': 'smallint',
|
1571
|
+
'成交转化率': 'decimal(10,4)',
|
1572
|
+
'atv': 'decimal(10,2)',
|
1573
|
+
'成交金额': 'decimal(12,2)',
|
1574
|
+
'退款人数': 'smallint',
|
1575
|
+
'index': 'smallint',
|
1576
|
+
'预售定金支付人数': 'smallint',
|
1577
|
+
'加购访客': 'smallint',
|
1578
|
+
'商品点击次数': 'int',
|
1579
|
+
'退款笔数': 'smallint',
|
1580
|
+
'itrt_uv': 'smallint',
|
1581
|
+
'成交人数': 'smallint',
|
1582
|
+
'观看总时长': 'varchar(100)',
|
1583
|
+
'加购访客转化率': 'decimal(10,4)',
|
1584
|
+
'subpay_order_cnt': 'smallint',
|
1585
|
+
'cmt_pv': 'int',
|
1586
|
+
'商品点击人数': 'int',
|
1587
|
+
'status': 'int',
|
1588
|
+
'商品曝光uv': 'int',
|
1589
|
+
'预售定金支付件数': 'smallint',
|
1590
|
+
'预售预估总金额': 'decimal(12,2)',
|
1591
|
+
'退款笔数占比': 'decimal(10,4)',
|
1592
|
+
'reward_pv': 'int',
|
1593
|
+
'访客点击量': 'int',
|
1594
|
+
'aiv': 'decimal(10,2)',
|
1595
|
+
'shr_uv': 'int',
|
1596
|
+
'浏览点击量': 'int',
|
1597
|
+
'场次图片': 'text',
|
1598
|
+
'user_role': 'varchar(100)',
|
1599
|
+
'退款人数占比': 'decimal(10,4)',
|
1600
|
+
'退款件数': 'smallint',
|
1601
|
+
'新增粉丝数': 'smallint',
|
1602
|
+
'场均观看时长': 'decimal(10,2)',
|
1603
|
+
'人均观看时长': 'decimal(10,2)',
|
1604
|
+
'加购人数': 'smallint',
|
1605
|
+
'reward_uv': 'smallint',
|
1606
|
+
'直播结束时间': 'datetime',
|
1607
|
+
'商品曝光pv': 'int',
|
1608
|
+
'shr_pv': 'int',
|
1609
|
+
'场次id': 'bigint',
|
1610
|
+
'look_pv_flowcontrol': 'smallint',
|
1611
|
+
'退款率': 'decimal(10,4)',
|
1612
|
+
'is_delete': 'varchar(50)',
|
1613
|
+
'atn_uv_rate': 'decimal(10,4)',
|
1614
|
+
'成交件数': 'smallint',
|
1615
|
+
'最大在线人数': 'int',
|
1616
|
+
'曝光uv': 'int',
|
1617
|
+
'加购件数': 'smallint',
|
1618
|
+
'预售定金支付金额': 'decimal(12,2)',
|
1619
|
+
'观看次数': 'int',
|
1620
|
+
'封面图': 'text',
|
1621
|
+
'更新时间': 'timestamp',
|
1622
|
+
}
|
1623
|
+
min_date = df['日期'].min()
|
1624
|
+
max_date = df['日期'].max()
|
1625
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
1626
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
1627
|
+
m_engine.df_to_mysql(
|
1628
|
+
df=df,
|
1629
|
+
db_name=db_name,
|
1630
|
+
table_name=table_name,
|
1631
|
+
icm_update=['场次id'], # 增量更新, 在聚合数据中使用,其他不要用
|
1632
|
+
move_insert=False, # 先删除,再插入
|
1633
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
1634
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
1635
|
+
count=None,
|
1636
|
+
filename=None, # 用来追踪处理进度
|
1637
|
+
reset_id=False, # 是否重置自增列
|
1638
|
+
set_typ=set_typ,
|
1639
|
+
)
|
1640
|
+
return True
|
581
1641
|
|
582
1642
|
# @try_except
|
583
|
-
def tg_by_day(self):
|
1643
|
+
def tg_by_day(self, db_name='聚合数据', table_name='多店推广场景_按日聚合'):
|
584
1644
|
"""
|
585
1645
|
汇总各个店铺的推广数据,按日汇总
|
586
1646
|
"""
|
@@ -768,26 +1828,71 @@ class MysqlDatasQuery:
|
|
768
1828
|
end_date=end_date,
|
769
1829
|
projection=projection,
|
770
1830
|
)
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
1831
|
+
if len(df_jd_qzyx) > 0:
|
1832
|
+
df_jd_qzyx = df_jd_qzyx.groupby(['日期', '店铺名称', '产品线', '花费'], as_index=False).agg(
|
1833
|
+
**{'全站投产比': ('全站投产比', np.max),
|
1834
|
+
'成交金额': ('全站交易额', np.max),
|
1835
|
+
'成交笔数': ('全站订单行', np.max),
|
1836
|
+
'全站订单成本': ('全站订单成本', np.max),
|
1837
|
+
'全站费比': ('全站费比', np.max),
|
1838
|
+
'展现量': ('核心位置展现量', np.max),
|
1839
|
+
'点击量': ('核心位置点击量', np.max),
|
1840
|
+
}
|
1841
|
+
)
|
1842
|
+
df_jd_qzyx.rename(columns={'产品线': '营销场景'}, inplace=True)
|
1843
|
+
df_jd_qzyx = df_jd_qzyx[['日期', '店铺名称', '营销场景', '花费', '展现量', '点击量', '成交笔数', '成交金额']]
|
1844
|
+
df_jd_qzyx = df_jd_qzyx[df_jd_qzyx['花费'] > 0]
|
784
1845
|
|
785
1846
|
_datas = [item for item in [df_tm, df_tb, df_tm_pxb, df_tm_living, df_jd, df_jd_qzyx] if len(item) > 0] # 阻止空的 dataframe
|
786
1847
|
df = pd.concat(_datas, axis=0, ignore_index=True)
|
787
|
-
|
1848
|
+
df['日期'] = pd.to_datetime(df['日期'], format='%Y-%m-%d', errors='ignore') # 转换日期列
|
1849
|
+
df = df.groupby(
|
1850
|
+
['日期', '店铺名称', '营销场景'],
|
1851
|
+
as_index=False).agg(
|
1852
|
+
**{
|
1853
|
+
'花费': ('花费', np.sum),
|
1854
|
+
'展现量': ('展现量', np.sum),
|
1855
|
+
'点击量': ('点击量', np.sum),
|
1856
|
+
'加购量': ('加购量', np.sum),
|
1857
|
+
'成交笔数': ('成交笔数', np.sum),
|
1858
|
+
'成交金额': ('成交金额', np.sum)
|
1859
|
+
}
|
1860
|
+
)
|
1861
|
+
df.sort_values(['日期', '店铺名称', '花费'], ascending=[False, False, False], ignore_index=True, inplace=True)
|
1862
|
+
set_typ = {
|
1863
|
+
'日期': 'date',
|
1864
|
+
'店铺名称': 'varchar(100)',
|
1865
|
+
'营销场景': 'varchar(100)',
|
1866
|
+
'花费': 'decimal(12,2)',
|
1867
|
+
'展现量': 'int',
|
1868
|
+
'点击量': 'int',
|
1869
|
+
'加购量': 'int',
|
1870
|
+
'成交笔数': 'int',
|
1871
|
+
'成交金额': 'decimal(12,2)',
|
1872
|
+
}
|
1873
|
+
if not self.update_service:
|
1874
|
+
return
|
1875
|
+
min_date = df['日期'].min()
|
1876
|
+
max_date = df['日期'].max()
|
1877
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
1878
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
1879
|
+
m_engine.df_to_mysql(
|
1880
|
+
df=df,
|
1881
|
+
db_name=db_name,
|
1882
|
+
table_name=table_name,
|
1883
|
+
icm_update=[], # 增量更新, 在聚合数据中使用,其他不要用
|
1884
|
+
move_insert=False, # 先删除,再插入
|
1885
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
1886
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
1887
|
+
count=None,
|
1888
|
+
filename=None, # 用来追踪处理进度
|
1889
|
+
reset_id=False, # 是否重置自增列
|
1890
|
+
set_typ=set_typ,
|
1891
|
+
)
|
1892
|
+
return True
|
788
1893
|
|
789
1894
|
@try_except
|
790
|
-
def aikucun_bd_spu(self):
|
1895
|
+
def aikucun_bd_spu(self, db_name='聚合数据', table_name='爱库存_商品spu榜单'):
|
791
1896
|
start_date, end_date = self.months_data(num=self.months)
|
792
1897
|
projection = {
|
793
1898
|
'日期': 1,
|
@@ -833,10 +1938,45 @@ class MysqlDatasQuery:
|
|
833
1938
|
end_date=end_date,
|
834
1939
|
projection=projection,
|
835
1940
|
)
|
836
|
-
|
1941
|
+
df.drop_duplicates(
|
1942
|
+
subset=[
|
1943
|
+
'日期',
|
1944
|
+
'店铺名称',
|
1945
|
+
'spu_id',
|
1946
|
+
'访客量',
|
1947
|
+
'浏览量',
|
1948
|
+
'下单gmv',
|
1949
|
+
'成交gmv',
|
1950
|
+
], keep='last', inplace=True, ignore_index=True)
|
1951
|
+
set_typ = {
|
1952
|
+
'日期': 'date',
|
1953
|
+
'店铺名称': 'varchar(100)',
|
1954
|
+
'序号': 'int',
|
1955
|
+
'spu_id': 'varchar(100)',
|
1956
|
+
'图片': 'varchar(255)',
|
1957
|
+
'数据更新时间': 'timestamp',
|
1958
|
+
}
|
1959
|
+
min_date = df['日期'].min()
|
1960
|
+
max_date = df['日期'].max()
|
1961
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
1962
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
1963
|
+
m_engine.df_to_mysql(
|
1964
|
+
df=df,
|
1965
|
+
db_name=db_name,
|
1966
|
+
table_name=table_name,
|
1967
|
+
icm_update=[], # 增量更新, 在聚合数据中使用,其他不要用
|
1968
|
+
move_insert=False, # 先删除,再插入
|
1969
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
1970
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
1971
|
+
count=None,
|
1972
|
+
filename=None, # 用来追踪处理进度
|
1973
|
+
reset_id=False, # 是否重置自增列
|
1974
|
+
set_typ=set_typ,
|
1975
|
+
)
|
1976
|
+
return True
|
837
1977
|
|
838
1978
|
@try_except
|
839
|
-
def dmp_crowd(self):
|
1979
|
+
def dmp_crowd(self, db_name='聚合数据', table_name='达摩盘_人群报表'):
|
840
1980
|
start_date, end_date = self.months_data(num=self.months)
|
841
1981
|
projection = {
|
842
1982
|
'日期': 1,
|
@@ -876,702 +2016,71 @@ class MysqlDatasQuery:
|
|
876
2016
|
# df.to_csv('/Users/xigua/Downloads/test3.csv', index=False, header=True, encoding='utf-8_sig')
|
877
2017
|
# breakpoint()
|
878
2018
|
df.rename(columns={'消耗_元': '消耗'}, inplace=True)
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
'点击量': int,
|
945
|
-
'加购量': int,
|
946
|
-
'成交笔数': int,
|
947
|
-
'成交金额': float,
|
948
|
-
'自然流量曝光量': int,
|
949
|
-
'直接成交笔数': int,
|
950
|
-
'直接成交金额': float,
|
951
|
-
}, errors='raise')
|
952
|
-
if is_maximize:
|
953
|
-
df = df.groupby(['日期', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量'], as_index=False).agg(
|
954
|
-
**{'加购量': ('加购量', np.max),
|
955
|
-
'成交笔数': ('成交笔数', np.max),
|
956
|
-
'成交金额': ('成交金额', np.max),
|
957
|
-
'自然流量曝光量': ('自然流量曝光量', np.max),
|
958
|
-
'直接成交笔数': ('直接成交笔数', np.max),
|
959
|
-
'直接成交金额': ('直接成交金额', np.max)
|
960
|
-
}
|
961
|
-
)
|
962
|
-
else:
|
963
|
-
df = df.groupby(['日期', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量'], as_index=False).agg(
|
964
|
-
**{
|
965
|
-
'加购量': ('加购量', np.min),
|
966
|
-
'成交笔数': ('成交笔数', np.min),
|
967
|
-
'成交金额': ('成交金额', np.min),
|
968
|
-
'自然流量曝光量': ('自然流量曝光量', np.min),
|
969
|
-
'直接成交笔数': ('直接成交笔数', np.max),
|
970
|
-
'直接成交金额': ('直接成交金额', np.max)
|
971
|
-
}
|
972
|
-
)
|
973
|
-
df.insert(loc=1, column='推广渠道', value='万相台无界版') # df中插入新列
|
974
|
-
df_new = df.groupby(['日期', '店铺名称', '商品id'], as_index=False).agg(
|
975
|
-
**{
|
976
|
-
'花费': ('花费', np.sum),
|
977
|
-
'成交笔数': ('成交笔数', np.max),
|
978
|
-
'成交金额': ('成交金额', np.max),
|
979
|
-
'自然流量曝光量': ('自然流量曝光量', np.max),
|
980
|
-
'直接成交笔数': ('直接成交笔数', np.max),
|
981
|
-
'直接成交金额': ('直接成交金额', np.max)
|
982
|
-
}
|
983
|
-
)
|
984
|
-
self.data_tgyj.update(
|
985
|
-
{
|
986
|
-
table_name: df_new,
|
987
|
-
}
|
988
|
-
)
|
989
|
-
self.data_tgyj.update(
|
990
|
-
{
|
991
|
-
'天猫汇总表调用': df,
|
992
|
-
}
|
993
|
-
)
|
994
|
-
# df_pic:商品排序索引表, 给 powerbi 中的主推款排序用的,(从上月1号到今天的总花费进行排序)
|
995
|
-
today = datetime.date.today()
|
996
|
-
last_month = today - datetime.timedelta(days=30)
|
997
|
-
if last_month.month == 12:
|
998
|
-
year_my = today.year - 1
|
999
|
-
else:
|
1000
|
-
year_my = today.year
|
1001
|
-
# 截取 从上月1日 至 今天的花费数据, 推广款式按此数据从高到低排序(商品图+排序)
|
1002
|
-
df_pic_lin = df[df['店铺名称'] == '万里马官方旗舰店']
|
1003
|
-
df_pic = df_pic_lin.groupby(['日期', '商品id'], as_index=False).agg({'花费': 'sum'})
|
1004
|
-
df_pic = df_pic[~df_pic['商品id'].isin([''])] # 指定列中删除包含空值的行
|
1005
|
-
date_obj = datetime.datetime.strptime(f'{year_my}-{last_month.month}-01', '%Y-%m-%d').date()
|
1006
|
-
df_pic = df_pic[(df_pic['日期'] >= date_obj)]
|
1007
|
-
df_pic = df_pic.groupby(['商品id'], as_index=False).agg({'花费': 'sum'})
|
1008
|
-
df_pic.sort_values('花费', ascending=False, ignore_index=True, inplace=True)
|
1009
|
-
df_pic.reset_index(inplace=True)
|
1010
|
-
df_pic['index'] = df_pic['index'] + 100
|
1011
|
-
df_pic.rename(columns={'index': '商品索引'}, inplace=True)
|
1012
|
-
df_pic_new = pd.merge(df_pic_lin, df_pic, how='left', on=['商品id'])
|
1013
|
-
df_pic_new['商品索引'].fillna(1000, inplace=True)
|
1014
|
-
self.sp_index_datas = df_pic_new[['商品id', '商品索引']] # 商品索引表_主推排序调用
|
1015
|
-
return df
|
1016
|
-
elif '商品索引表' in table_name:
|
1017
|
-
return df
|
1018
|
-
elif '爱库存_商品spu榜单' in table_name:
|
1019
|
-
df.drop_duplicates(
|
1020
|
-
subset=[
|
1021
|
-
'日期',
|
1022
|
-
'店铺名称',
|
1023
|
-
'spu_id',
|
1024
|
-
'访客量',
|
1025
|
-
'浏览量',
|
1026
|
-
'下单gmv',
|
1027
|
-
'成交gmv',
|
1028
|
-
], keep='last', inplace=True, ignore_index=True)
|
1029
|
-
return df
|
1030
|
-
elif '天猫_人群报表' in table_name and '达摩盘' not in table_name:
|
1031
|
-
"""
|
1032
|
-
天猫推广人群报表独立生成消费力、年龄层、分类等特征,不依赖于达摩盘数据表
|
1033
|
-
"""
|
1034
|
-
df.rename(columns={
|
1035
|
-
'场景名字': '营销场景',
|
1036
|
-
'主体id': '商品id',
|
1037
|
-
'总购物车数': '加购量',
|
1038
|
-
'总成交笔数': '成交笔数',
|
1039
|
-
'总成交金额': '成交金额'
|
1040
|
-
}, inplace=True)
|
1041
|
-
df.fillna(0, inplace=True)
|
1042
|
-
df = df.astype({
|
1043
|
-
'商品id': str,
|
1044
|
-
'花费': float,
|
1045
|
-
'展现量': int,
|
1046
|
-
'点击量': int,
|
1047
|
-
'加购量': int,
|
1048
|
-
'成交笔数': int,
|
1049
|
-
'成交金额': float,
|
1050
|
-
'直接成交笔数': int,
|
1051
|
-
'直接成交金额': float,
|
1052
|
-
}, errors='raise')
|
1053
|
-
if is_maximize:
|
1054
|
-
df = df.groupby(['日期', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量', '人群名字'], as_index=False).agg(
|
1055
|
-
**{'加购量': ('加购量', np.max),
|
1056
|
-
'成交笔数': ('成交笔数', np.max),
|
1057
|
-
'成交金额': ('成交金额', np.max),
|
1058
|
-
'直接成交笔数': ('直接成交笔数', np.max),
|
1059
|
-
'直接成交金额': ('直接成交金额', np.max)
|
1060
|
-
}
|
1061
|
-
)
|
1062
|
-
else:
|
1063
|
-
df = df.groupby(['日期', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量', '人群名字'], as_index=False).agg(
|
1064
|
-
**{
|
1065
|
-
'加购量': ('加购量', np.min),
|
1066
|
-
'成交笔数': ('成交笔数', np.min),
|
1067
|
-
'成交金额': ('成交金额', np.min),
|
1068
|
-
'直接成交笔数': ('直接成交笔数', np.max),
|
1069
|
-
'直接成交金额': ('直接成交金额', np.max)
|
1070
|
-
}
|
1071
|
-
)
|
1072
|
-
df.insert(loc=1, column='推广渠道', value='万相台无界版') # df中插入新列
|
1073
|
-
# 1. 匹配 L后面接 2 个或以上数字,不区分大小写,示例:L345
|
1074
|
-
# 2. 其余情况,L 后面接多个数字的都会被第一条 if 命中,不区分大小写
|
1075
|
-
df['消费力层级'] = df.apply(
|
1076
|
-
lambda x:
|
1077
|
-
''.join(re.findall(r'(l\d+)', x['人群名字'].upper(), re.IGNORECASE)) if re.findall(r'(l\d{2,})', x['人群名字'], re.IGNORECASE)
|
1078
|
-
else 'L5' if re.findall(r'(l\d*5)', x['人群名字'], re.IGNORECASE)
|
1079
|
-
else 'L4' if re.findall(r'(l\d*4)', x['人群名字'], re.IGNORECASE)
|
1080
|
-
else 'L3' if re.findall(r'(l\d*3)', x['人群名字'], re.IGNORECASE)
|
1081
|
-
else 'L2' if re.findall(r'(l\d*2)', x['人群名字'], re.IGNORECASE)
|
1082
|
-
else 'L1' if re.findall(r'(l\d*1)', x['人群名字'], re.IGNORECASE)
|
1083
|
-
else '', axis=1)
|
1084
|
-
# 1. 匹配连续的 4 个数字且后面不能接数字或"元"或汉字,筛掉的人群示例:月均消费6000元|受众20240729175213|xxx2024真皮公文包
|
1085
|
-
# 2. 匹配 2数字_2数字且前面不能是数字,合法匹配:人群_30_50_促; 非法示例:L345_3040 避免识别出 35~20 岁用户的情况
|
1086
|
-
# pattern = r'(\d{4})(?!\d|[\u4e00-\u9fa5])' # 匹配 4 个数字,后面不能接数字或汉字
|
1087
|
-
# pattern = r'(?<![\d\u4e00-\u9fa5])(\d{4})' # 匹配前面不是数字或汉字的 4 个连续数字
|
1088
|
-
|
1089
|
-
# 匹配 4 个数字,前面和后面都不能是数字或汉字
|
1090
|
-
pattern1 = r'(?<![\d\u4e00-\u9fa5])(\d{4})(?!\d|[\u4e00-\u9fa5])'
|
1091
|
-
# 匹配指定字符,前面不能是数字或 l 或 L 开头
|
1092
|
-
pattern2 = r'(?<![\dlL])(\d{2}_\d{2})'
|
1093
|
-
df['用户年龄'] = df.apply(
|
1094
|
-
lambda x:
|
1095
|
-
''.join(re.findall(pattern1, x['人群名字'].upper())) if re.findall(pattern1, x['人群名字'])
|
1096
|
-
# else ''.join(re.findall(r'[^\d|l|L](\d{2}_\d{2})', x['人群名字'].upper())) if re.findall(r'[^\d|l|L](\d{2}_\d{2})', x['人群名字'])
|
1097
|
-
else ''.join(re.findall(pattern2, x['人群名字'].upper())) if re.findall(pattern2, x['人群名字'])
|
1098
|
-
else ''.join(re.findall(r'(\d{2}-\d{2})岁', x['人群名字'].upper())) if re.findall(r'(\d{2}-\d{2})岁', x['人群名字'])
|
1099
|
-
else '', axis=1)
|
1100
|
-
df['用户年龄'] = df['用户年龄'].apply(
|
1101
|
-
lambda x: f'{x[:2]}~{x[2:4]}' if str(x).isdigit()
|
1102
|
-
else str(x).replace('_', '~') if '_' in x
|
1103
|
-
else str(x).replace('-', '~') if '-' in x
|
1104
|
-
else x
|
1105
|
-
)
|
1106
|
-
# 年龄层不能是 0 开头
|
1107
|
-
df['用户年龄'] = df['用户年龄'].apply(
|
1108
|
-
lambda x: '' if str(x).startswith('0') else x)
|
1109
|
-
# df = df.head(1000)
|
1110
|
-
# df.to_csv('/Users/xigua/Downloads/test.csv', index=False, header=True, encoding='utf-8_sig')
|
1111
|
-
# breakpoint()
|
1112
|
-
|
1113
|
-
# 下面是添加人群 AIPL 分类
|
1114
|
-
dir_file = f'\\\\192.168.1.198\\时尚事业部\\01.运营部\\0-电商周报-每周五更新\\分类配置文件.xlsx'
|
1115
|
-
dir_file2 = '/Volumes/时尚事业部/01.运营部/0-电商周报-每周五更新/分类配置文件.xlsx'
|
1116
|
-
if platform.system() == 'Windows':
|
1117
|
-
dir_file3 = 'C:\\同步空间\\BaiduSyncdisk\\原始文件2\\分类配置文件.xlsx'
|
1118
|
-
else:
|
1119
|
-
dir_file3 = '/Users/xigua/数据中心/原始文件2/分类配置文件.xlsx'
|
1120
|
-
if not os.path.isfile(dir_file):
|
1121
|
-
dir_file = dir_file2
|
1122
|
-
if not os.path.isfile(dir_file):
|
1123
|
-
dir_file = dir_file3
|
1124
|
-
if os.path.isfile(dir_file):
|
1125
|
-
df_fl = pd.read_excel(dir_file, sheet_name='人群分类', header=0)
|
1126
|
-
df_fl = df_fl[['人群名字', '人群分类']]
|
1127
|
-
# 合并并获取分类信息
|
1128
|
-
df = pd.merge(df, df_fl, left_on=['人群名字'], right_on=['人群名字'], how='left')
|
1129
|
-
df['人群分类'].fillna('', inplace=True)
|
1130
|
-
if '人群分类' in df.columns.tolist():
|
1131
|
-
# 这行决定了,从文件中读取的分类信息优先级高于内部函数的分类规则
|
1132
|
-
# 这个 lambda 适配人群名字中带有特定标识的分类,强匹配
|
1133
|
-
df['人群分类'] = df.apply(
|
1134
|
-
lambda x: self.set_crowd(keyword=str(x['人群名字']), as_file=False) if x['人群分类'] == ''
|
1135
|
-
else x['人群分类'], axis=1
|
1136
|
-
)
|
1137
|
-
# 这个 lambda 适配人群名字中聚类的特征字符,弱匹配
|
1138
|
-
df['人群分类'] = df.apply(
|
1139
|
-
lambda x: self.set_crowd2(keyword=str(x['人群名字']), as_file=False) if x['人群分类'] == ''
|
1140
|
-
else x['人群分类'], axis=1
|
1141
|
-
)
|
1142
|
-
else:
|
1143
|
-
df['人群分类'] = df['人群名字'].apply(lambda x: self.set_crowd(keyword=str(x), as_file=False))
|
1144
|
-
df['人群分类'] = df.apply(
|
1145
|
-
lambda x: self.set_crowd2(keyword=str(x['人群名字']), as_file=False) if x['人群分类'] == ''
|
1146
|
-
else x['人群分类'], axis=1
|
1147
|
-
)
|
1148
|
-
df['人群分类'] = df['人群分类'].apply(lambda x: str(x).upper() if x else x)
|
1149
|
-
# df.to_csv('/Users/xigua/Downloads/test_人群分类.csv', index=False, header=True, encoding='utf-8_sig')
|
1150
|
-
# breakpoint()
|
1151
|
-
return df
|
1152
|
-
elif '天猫_关键词报表' in table_name:
|
1153
|
-
df.rename(columns={
|
1154
|
-
'场景名字': '营销场景',
|
1155
|
-
'宝贝id': '商品id',
|
1156
|
-
'总购物车数': '加购量',
|
1157
|
-
'总成交笔数': '成交笔数',
|
1158
|
-
'总成交金额': '成交金额'
|
1159
|
-
}, inplace=True)
|
1160
|
-
df.fillna(0, inplace=True)
|
1161
|
-
df = df.astype({
|
1162
|
-
'商品id': str,
|
1163
|
-
'花费': float,
|
1164
|
-
'展现量': int,
|
1165
|
-
'点击量': int,
|
1166
|
-
'加购量': int,
|
1167
|
-
'成交笔数': int,
|
1168
|
-
'成交金额': float,
|
1169
|
-
'直接成交笔数': int,
|
1170
|
-
'直接成交金额': float,
|
1171
|
-
}, errors='raise')
|
1172
|
-
if is_maximize:
|
1173
|
-
df = df.groupby(['日期', '店铺名称', '营销场景', '商品id', '词类型', '词名字_词包名字', '花费', '展现量', '点击量'], as_index=False).agg(
|
1174
|
-
**{'加购量': ('加购量', np.max),
|
1175
|
-
'成交笔数': ('成交笔数', np.max),
|
1176
|
-
'成交金额': ('成交金额', np.max),
|
1177
|
-
'直接成交笔数': ('直接成交笔数', np.max),
|
1178
|
-
'直接成交金额': ('直接成交金额', np.max)
|
1179
|
-
}
|
1180
|
-
)
|
1181
|
-
else:
|
1182
|
-
df = df.groupby(['日期', '店铺名称', '营销场景', '商品id', '词类型', '词名字_词包名字', '花费', '展现量', '点击量'], as_index=False).agg(
|
1183
|
-
**{
|
1184
|
-
'加购量': ('加购量', np.min),
|
1185
|
-
'成交笔数': ('成交笔数', np.min),
|
1186
|
-
'成交金额': ('成交金额', np.min),
|
1187
|
-
'直接成交笔数': ('直接成交笔数', np.max),
|
1188
|
-
'直接成交金额': ('直接成交金额', np.max)
|
1189
|
-
}
|
1190
|
-
)
|
1191
|
-
df.insert(loc=1, column='推广渠道', value='万相台无界版') # df中插入新列
|
1192
|
-
df['是否品牌词'] = df['词名字_词包名字'].str.contains('万里马|wanlima', regex=True)
|
1193
|
-
df['是否品牌词'] = df['是否品牌词'].apply(lambda x: '品牌词' if x else '')
|
1194
|
-
dir_file = f'\\\\192.168.1.198\\时尚事业部\\01.运营部\\0-电商周报-每周五更新\\分类配置文件.xlsx'
|
1195
|
-
dir_file2 = '/Volumes/时尚事业部/01.运营部/0-电商周报-每周五更新/分类配置文件.xlsx'
|
1196
|
-
if not os.path.isfile(dir_file):
|
1197
|
-
dir_file = dir_file2
|
1198
|
-
if os.path.isfile(dir_file):
|
1199
|
-
df_fl = pd.read_excel(dir_file, sheet_name='关键词分类', header=0)
|
1200
|
-
# df_fl.rename(columns={'分类1': '词分类'}, inplace=True)
|
1201
|
-
df_fl = df_fl[['关键词', '词分类']]
|
1202
|
-
# 合并并获取词分类信息
|
1203
|
-
df = pd.merge(df, df_fl, left_on=['词名字_词包名字'], right_on=['关键词'], how='left')
|
1204
|
-
df.pop('关键词')
|
1205
|
-
df['词分类'].fillna('', inplace=True)
|
1206
|
-
if '词分类' in df.columns.tolist():
|
1207
|
-
# 这行决定了,从文件中读取的词分类信息优先级高于 ret_keyword 函数的词分类
|
1208
|
-
df['词分类'] = df.apply(
|
1209
|
-
lambda x: self.ret_keyword(keyword=str(x['词名字_词包名字']), as_file=False) if x['词分类'] == ''
|
1210
|
-
else x['词分类'], axis=1
|
1211
|
-
)
|
1212
|
-
else:
|
1213
|
-
df['词分类'] = df['词名字_词包名字'].apply(lambda x: self.ret_keyword(keyword=str(x), as_file=False))
|
1214
|
-
# df.to_csv('/Users/xigua/Downloads/test.csv', index=False, header=True, encoding='utf-8_sig')
|
1215
|
-
# breakpoint()
|
1216
|
-
return df
|
1217
|
-
elif '天猫_超级直播' in table_name:
|
1218
|
-
df.rename(columns={
|
1219
|
-
'观看次数': '观看次数',
|
1220
|
-
'总购物车数': '加购量',
|
1221
|
-
'总成交笔数': '成交笔数',
|
1222
|
-
'总成交金额': '成交金额',
|
1223
|
-
'场景名字': '营销场景',
|
1224
|
-
}, inplace=True)
|
1225
|
-
df['营销场景'] = '超级直播'
|
1226
|
-
df.fillna(0, inplace=True)
|
1227
|
-
df = df.astype({
|
1228
|
-
'花费': float,
|
1229
|
-
# '点击量': int,
|
1230
|
-
'加购量': int,
|
1231
|
-
'成交笔数': int,
|
1232
|
-
'成交金额': float,
|
1233
|
-
'进店量': int,
|
1234
|
-
'粉丝关注量': int,
|
1235
|
-
'观看次数': int,
|
1236
|
-
}, errors='raise')
|
1237
|
-
if is_maximize:
|
1238
|
-
df = df.groupby(['日期', '店铺名称', '营销场景', '人群名字', '计划名字', '花费', '观看次数', '展现量'],
|
1239
|
-
as_index=False).agg(
|
1240
|
-
**{
|
1241
|
-
'进店量': ('进店量', np.max),
|
1242
|
-
'粉丝关注量': ('粉丝关注量', np.max),
|
1243
|
-
'加购量': ('加购量', np.max),
|
1244
|
-
'成交笔数': ('成交笔数', np.max),
|
1245
|
-
'成交金额': ('成交金额', np.max),
|
1246
|
-
'直接成交笔数': ('直接成交笔数', np.max),
|
1247
|
-
'直接成交金额': ('直接成交金额', np.max),
|
1248
|
-
}
|
1249
|
-
)
|
1250
|
-
else:
|
1251
|
-
df = df.groupby(['日期', '店铺名称', '营销场景', '人群名字', '计划名字', '花费', '观看次数', '展现量'],
|
1252
|
-
as_index=False).agg(
|
1253
|
-
**{
|
1254
|
-
'进店量': ('进店量', np.min),
|
1255
|
-
'粉丝关注量': ('粉丝关注量', np.min),
|
1256
|
-
'加购量': ('加购量', np.min),
|
1257
|
-
'成交笔数': ('成交笔数', np.min),
|
1258
|
-
'成交金额': ('成交金额', np.min),
|
1259
|
-
'直接成交笔数': ('直接成交笔数', np.min),
|
1260
|
-
'直接成交金额': ('直接成交金额', np.min),
|
1261
|
-
}
|
1262
|
-
)
|
1263
|
-
df.insert(loc=1, column='推广渠道', value='万相台无界版') # df中插入新列
|
1264
|
-
# df.insert(loc=2, column='营销场景', value='超级直播') # df中插入新列
|
1265
|
-
# df = df.loc[df['日期'].between(start_day, today)]
|
1266
|
-
df_new = df.groupby(['日期', '店铺名称', '推广渠道', '营销场景'], as_index=False).agg(
|
1267
|
-
**{
|
1268
|
-
'花费': ('花费', np.sum),
|
1269
|
-
'展现量': ('展现量', np.sum),
|
1270
|
-
'观看次数': ('观看次数', np.sum),
|
1271
|
-
'加购量': ('加购量', np.sum),
|
1272
|
-
'成交笔数': ('成交笔数', np.sum),
|
1273
|
-
'成交金额': ('成交金额', np.sum),
|
1274
|
-
'直接成交笔数': ('直接成交笔数', np.sum),
|
1275
|
-
'直接成交金额': ('直接成交金额', np.sum),
|
1276
|
-
}
|
1277
|
-
)
|
1278
|
-
self.data_tgyj.update(
|
1279
|
-
{
|
1280
|
-
table_name: df_new,
|
1281
|
-
}
|
1282
|
-
)
|
1283
|
-
return df
|
1284
|
-
elif '天猫_品销宝账户报表' in table_name:
|
1285
|
-
df = df[df['报表类型'] == '账户']
|
1286
|
-
df.fillna(value=0, inplace=True)
|
1287
|
-
df.rename(columns={
|
1288
|
-
'消耗': '花费',
|
1289
|
-
'宝贝加购数': '加购量',
|
1290
|
-
'搜索量': '品牌搜索量',
|
1291
|
-
'搜索访客数': '品牌搜索人数'
|
1292
|
-
}, inplace=True)
|
1293
|
-
df = df.astype({
|
1294
|
-
'花费': float,
|
1295
|
-
'展现量': int,
|
1296
|
-
'点击量': int,
|
1297
|
-
'加购量': int,
|
1298
|
-
'成交笔数': int,
|
1299
|
-
'成交金额': float,
|
1300
|
-
'品牌搜索量': int,
|
1301
|
-
'品牌搜索人数': int,
|
1302
|
-
}, errors='raise')
|
1303
|
-
if is_maximize:
|
1304
|
-
df = df.groupby(['日期', '店铺名称', '报表类型', '花费', '展现量', '点击量'], as_index=False).agg(
|
1305
|
-
**{
|
1306
|
-
'加购量': ('加购量', np.max),
|
1307
|
-
'成交笔数': ('成交笔数', np.max),
|
1308
|
-
'成交金额': ('成交金额', np.max),
|
1309
|
-
'品牌搜索量': ('品牌搜索量', np.max),
|
1310
|
-
'品牌搜索人数': ('品牌搜索人数', np.max),
|
1311
|
-
}
|
1312
|
-
)
|
1313
|
-
else:
|
1314
|
-
df = df.groupby(['日期', '店铺名称', '报表类型', '花费', '展现量', '点击量'], as_index=False).agg(
|
1315
|
-
**{
|
1316
|
-
'加购量': ('加购量', np.min),
|
1317
|
-
'成交笔数': ('成交笔数', np.min),
|
1318
|
-
'成交金额': ('成交金额', np.min),
|
1319
|
-
'品牌搜索量': ('品牌搜索量', np.min),
|
1320
|
-
'品牌搜索人数': ('品牌搜索人数', np.min),
|
1321
|
-
}
|
1322
|
-
)
|
1323
|
-
df.insert(loc=1, column='推广渠道', value='品销宝') # df中插入新列
|
1324
|
-
df.insert(loc=2, column='营销场景', value='品销宝') # df中插入新列
|
1325
|
-
df_new = df.groupby(['日期', '店铺名称', '推广渠道', '营销场景'], as_index=False).agg(
|
1326
|
-
**{
|
1327
|
-
'花费': ('花费', np.sum),
|
1328
|
-
'展现量': ('展现量', np.sum),
|
1329
|
-
'点击量': ('点击量', np.sum),
|
1330
|
-
'加购量': ('加购量', np.sum),
|
1331
|
-
'成交笔数': ('成交笔数', np.sum),
|
1332
|
-
'成交金额': ('成交金额', np.sum)
|
1333
|
-
}
|
1334
|
-
)
|
1335
|
-
self.data_tgyj.update(
|
1336
|
-
{
|
1337
|
-
table_name: df_new,
|
1338
|
-
}
|
1339
|
-
)
|
1340
|
-
return df
|
1341
|
-
elif '宝贝指标' in table_name:
|
1342
|
-
""" 聚合时不可以加商家编码,编码有些是空白,有些是 0 """
|
1343
|
-
df['宝贝id'] = df['宝贝id'].astype(str)
|
1344
|
-
df.fillna(0, inplace=True)
|
1345
|
-
# df = df[(df['销售额'] != 0) | (df['退款额'] != 0)] # 注释掉, 因为后续使用生意经作为基准合并推广表,需确保所有商品id 齐全
|
1346
|
-
df = df.groupby(['日期', '店铺名称', '宝贝id', '行业类目'], as_index=False).agg(
|
1347
|
-
**{'销售额': ('销售额', np.min),
|
1348
|
-
'销售量': ('销售量', np.min),
|
1349
|
-
'订单数': ('订单数', np.min),
|
1350
|
-
'退货量': ('退货量', np.max),
|
1351
|
-
'退款额': ('退款额', np.max),
|
1352
|
-
'退款额_发货后': ('退款额_发货后', np.max),
|
1353
|
-
'退货量_发货后': ('退货量_发货后', np.max),
|
1354
|
-
}
|
1355
|
-
)
|
1356
|
-
df['件均价'] = df.apply(lambda x: x['销售额'] / x['销售量'] if x['销售量'] > 0 else 0, axis=1).round(
|
1357
|
-
0) # 两列运算, 避免除以0
|
1358
|
-
df['价格带'] = df['件均价'].apply(
|
1359
|
-
lambda x: '2000+' if x >= 2000
|
1360
|
-
else '1000+' if x >= 1000
|
1361
|
-
else '500+' if x >= 500
|
1362
|
-
else '300+' if x >= 300
|
1363
|
-
else '300以下'
|
1364
|
-
)
|
1365
|
-
self.data_tgyj.update(
|
1366
|
-
{
|
1367
|
-
table_name: df[['日期', '店铺名称', '宝贝id', '销售额', '销售量', '退款额_发货后', '退货量_发货后']],
|
1368
|
-
}
|
1369
|
-
)
|
1370
|
-
return df
|
1371
|
-
elif '店铺流量来源构成' in table_name:
|
1372
|
-
# 包含三级来源名称和预设索引值列
|
1373
|
-
# 截取 从上月1日 至 今天的花费数据, 推广款式按此数据从高到低排序(商品图+排序)
|
1374
|
-
df_visitor3 = df.groupby(['日期', '三级来源'], as_index=False).agg({'访客数': 'sum'})
|
1375
|
-
df_visitor3 = df_visitor3[~df_visitor3['三级来源'].isin([''])] # 指定列中删除包含空值的行
|
1376
|
-
# df_visitor = df_visitor[(df_visitor['日期'] >= f'{year_my}-{last_month.month}-01')]
|
1377
|
-
df_visitor3 = df_visitor3.groupby(['三级来源'], as_index=False).agg({'访客数': 'sum'})
|
1378
|
-
df_visitor3.sort_values('访客数', ascending=False, ignore_index=True, inplace=True)
|
1379
|
-
df_visitor3.reset_index(inplace=True)
|
1380
|
-
df_visitor3['index'] = df_visitor3['index'] + 100
|
1381
|
-
df_visitor3.rename(columns={'index': '三级访客索引'}, inplace=True)
|
1382
|
-
df_visitor3 = df_visitor3[['三级来源', '三级访客索引']]
|
1383
|
-
|
1384
|
-
# 包含二级来源名称和预设索引值列
|
1385
|
-
df_visitor2 = df.groupby(['日期', '二级来源'], as_index=False).agg({'访客数': 'sum'})
|
1386
|
-
df_visitor2 = df_visitor2[~df_visitor2['二级来源'].isin([''])] # 指定列中删除包含空值的行
|
1387
|
-
# df_visitor2 = df_visitor2[(df_visitor2['日期'] >= f'{year_my}-{last_month.month}-01')]
|
1388
|
-
df_visitor2 = df_visitor2.groupby(['二级来源'], as_index=False).agg({'访客数': 'sum'})
|
1389
|
-
df_visitor2.sort_values('访客数', ascending=False, ignore_index=True, inplace=True)
|
1390
|
-
df_visitor2.reset_index(inplace=True)
|
1391
|
-
df_visitor2['index'] = df_visitor2['index'] + 100
|
1392
|
-
df_visitor2.rename(columns={'index': '二级访客索引'}, inplace=True)
|
1393
|
-
df_visitor2 = df_visitor2[['二级来源', '二级访客索引']]
|
1394
|
-
|
1395
|
-
df = pd.merge(df, df_visitor2, how='left', left_on='二级来源', right_on='二级来源')
|
1396
|
-
df = pd.merge(df, df_visitor3, how='left', left_on='三级来源', right_on='三级来源')
|
1397
|
-
return df
|
1398
|
-
elif '商品id编码表' in table_name:
|
1399
|
-
df['宝贝id'] = df['宝贝id'].astype(str)
|
1400
|
-
df.drop_duplicates(subset='宝贝id', keep='last', inplace=True, ignore_index=True)
|
1401
|
-
# df['行业类目'] = df['行业类目'].apply(lambda x: re.sub(' ', '', x))
|
1402
|
-
try:
|
1403
|
-
df[['一级类目', '二级类目', '三级类目']] = df['行业类目'].str.split(' -> ', expand=True).loc[:, 0:2]
|
1404
|
-
except:
|
1405
|
-
try:
|
1406
|
-
df[['一级类目', '二级类目']] = df['行业类目'].str.split(' -> ', expand=True).loc[:, 0:1]
|
1407
|
-
except:
|
1408
|
-
df['一级类目'] = df['行业类目']
|
1409
|
-
df.drop('行业类目', axis=1, inplace=True)
|
1410
|
-
df.sort_values('宝贝id', ascending=False, inplace=True)
|
1411
|
-
df = df[(df['宝贝id'] != '973') & (df['宝贝id'] != '973')]
|
1412
|
-
self.data_tgyj.update(
|
1413
|
-
{
|
1414
|
-
table_name: df[['宝贝id', '商家编码']],
|
1415
|
-
}
|
1416
|
-
)
|
1417
|
-
return df
|
1418
|
-
elif '商品id图片对照表' in table_name:
|
1419
|
-
df['商品id'] = df['商品id'].astype('int64')
|
1420
|
-
df['日期'] = df['日期'].astype('datetime64[ns]')
|
1421
|
-
df = df[(df['商品白底图'] != '0') | (df['方版场景图'] != '0')]
|
1422
|
-
# 白底图优先
|
1423
|
-
df['商品图片'] = df[['商品白底图', '方版场景图']].apply(
|
1424
|
-
lambda x: x['商品白底图'] if x['商品白底图'] !='0' else x['方版场景图'], axis=1)
|
1425
|
-
# # 方版场景图优先
|
1426
|
-
# df['商品图片'] = df[['商品白底图', '方版场景图']].apply(
|
1427
|
-
# lambda x: x['方版场景图'] if x['方版场景图'] != '0' else x['商品白底图'], axis=1)
|
1428
|
-
df.sort_values(by=['商品id', '日期'], ascending=[False, True], ignore_index=True, inplace=True)
|
1429
|
-
df.drop_duplicates(subset=['商品id'], keep='last', inplace=True, ignore_index=True)
|
1430
|
-
df = df[['商品id', '商品图片', '日期']]
|
1431
|
-
df['商品图片'] = df['商品图片'].apply(lambda x: x if 'http' in x else None) # 检查是否是 http 链接
|
1432
|
-
df.dropna(how='all', subset=['商品图片'], axis=0, inplace=True) # 删除指定列含有空值的行
|
1433
|
-
df['商品链接'] = df['商品id'].apply(
|
1434
|
-
lambda x: f'https://detail.tmall.com/item.htm?id={str(x)}' if x and '.com' not in str(x) else x)
|
1435
|
-
df.sort_values(by='商品id', ascending=False, ignore_index=True, inplace=True) # ascending=False 降序排列
|
1436
|
-
self.data_tgyj.update(
|
1437
|
-
{
|
1438
|
-
table_name: df[['商品id', '商品图片']],
|
1439
|
-
}
|
1440
|
-
)
|
1441
|
-
df['商品id'] = df['商品id'].astype(str)
|
1442
|
-
return df
|
1443
|
-
elif '商品成本' in table_name:
|
1444
|
-
df.sort_values(by=['款号', '日期'], ascending=[False, True], ignore_index=True, inplace=True)
|
1445
|
-
df.drop_duplicates(subset=['款号'], keep='last', inplace=True, ignore_index=True)
|
1446
|
-
self.data_tgyj.update(
|
1447
|
-
{
|
1448
|
-
table_name: df[['款号', '成本价']],
|
1449
|
-
}
|
1450
|
-
)
|
1451
|
-
return df
|
1452
|
-
elif '京东_京准通' in table_name and '全站营销' not in table_name:
|
1453
|
-
df = df.groupby(['日期', '店铺名称', '产品线', '触发sku_id', '跟单sku_id', 'spu_id', '花费', '展现数', '点击数'], as_index=False).agg(
|
1454
|
-
**{'直接订单行': ('直接订单行', np.max),
|
1455
|
-
'直接订单金额': ('直接订单金额', np.max),
|
1456
|
-
'总订单行': ('总订单行', np.max),
|
1457
|
-
'总订单金额': ('总订单金额', np.max),
|
1458
|
-
'直接加购数': ('直接加购数', np.max),
|
1459
|
-
'总加购数': ('总加购数', np.max),
|
1460
|
-
}
|
1461
|
-
)
|
1462
|
-
df = df[df['花费'] > 0]
|
1463
|
-
self.data_jdtg.update(
|
1464
|
-
{
|
1465
|
-
table_name: df[['日期', '产品线', '触发sku_id', '跟单sku_id', '花费']],
|
1466
|
-
}
|
1467
|
-
)
|
1468
|
-
return df
|
1469
|
-
elif '京东_京准通_全站营销' in table_name:
|
1470
|
-
df = df.groupby(['日期', '产品线', '花费'], as_index=False).agg(
|
1471
|
-
**{'全站投产比': ('全站投产比', np.max),
|
1472
|
-
'全站交易额': ('全站交易额', np.max),
|
1473
|
-
'全站订单行': ('全站订单行', np.max),
|
1474
|
-
'全站订单成本': ('全站订单成本', np.max),
|
1475
|
-
'全站费比': ('全站费比', np.max),
|
1476
|
-
'核心位置展现量': ('核心位置展现量', np.max),
|
1477
|
-
'核心位置点击量': ('核心位置点击量', np.max),
|
1478
|
-
}
|
1479
|
-
)
|
1480
|
-
df = df[df['花费'] > 0]
|
1481
|
-
return df
|
1482
|
-
elif '京东_sku_商品明细' in table_name:
|
1483
|
-
df = df[df['商品id'] != '合计']
|
1484
|
-
df = df.groupby(['日期', '商品id', '货号', '访客数', '成交客户数', '加购商品件数', '加购人数'],
|
1485
|
-
as_index=False).agg(
|
1486
|
-
**{
|
1487
|
-
'成交单量': ('成交单量', np.max),
|
1488
|
-
'成交金额': ('成交金额', np.max),
|
1489
|
-
}
|
1490
|
-
)
|
1491
|
-
self.data_jdtg.update(
|
1492
|
-
{
|
1493
|
-
table_name: df,
|
1494
|
-
}
|
1495
|
-
)
|
1496
|
-
return df
|
1497
|
-
elif '京东_spu_商品明细' in table_name:
|
1498
|
-
df = df[df['商品id'] != '合计']
|
1499
|
-
df = df.groupby(['日期', '商品id', '货号', '访客数', '成交客户数', '加购商品件数', '加购人数'],
|
1500
|
-
as_index=False).agg(
|
1501
|
-
**{
|
1502
|
-
'成交单量': ('成交单量', np.max),
|
1503
|
-
'成交金额': ('成交金额', np.max),
|
1504
|
-
}
|
1505
|
-
)
|
1506
|
-
self.data_jdtg.update(
|
1507
|
-
{
|
1508
|
-
table_name: df,
|
1509
|
-
}
|
1510
|
-
)
|
1511
|
-
return df
|
1512
|
-
elif '京东_关键词报表' in table_name:
|
1513
|
-
df_lin = df[['计划id', '推广计划']]
|
1514
|
-
df_lin.drop_duplicates(subset=['计划id'], keep='last', inplace=True, ignore_index=True)
|
1515
|
-
df = df.groupby(['日期', '产品线', '计划类型', '计划id', '搜索词', '关键词', '关键词购买类型', '广告定向类型', '展现数', '点击数', '花费'],
|
1516
|
-
as_index=False).agg(
|
1517
|
-
**{
|
1518
|
-
'直接订单行': ('直接订单行', np.max),
|
1519
|
-
'直接订单金额': ('直接订单金额', np.max),
|
1520
|
-
'总订单行': ('总订单行', np.max),
|
1521
|
-
'总订单金额': ('总订单金额', np.max),
|
1522
|
-
'总加购数': ('总加购数', np.max),
|
1523
|
-
'领券数': ('领券数', np.max),
|
1524
|
-
'商品关注数': ('商品关注数', np.max),
|
1525
|
-
'店铺关注数': ('店铺关注数', np.max)
|
1526
|
-
}
|
1527
|
-
)
|
1528
|
-
df = pd.merge(df, df_lin, how='left', left_on='计划id', right_on='计划id')
|
1529
|
-
df['k_是否品牌词'] = df['关键词'].str.contains('万里马|wanlima', regex=True)
|
1530
|
-
df['k_是否品牌词'] = df['k_是否品牌词'].apply(lambda x: '品牌词' if x else '')
|
1531
|
-
df['s_是否品牌词'] = df['搜索词'].str.contains('万里马|wanlima', regex=True)
|
1532
|
-
df['s_是否品牌词'] = df['s_是否品牌词'].apply(lambda x: '品牌词' if x else '')
|
1533
|
-
return df
|
1534
|
-
elif '天猫店铺来源_手淘搜索' in table_name:
|
1535
|
-
df = df.groupby(
|
1536
|
-
['日期', '店铺名称', '词类型', '搜索词'],
|
1537
|
-
as_index=False).agg(
|
1538
|
-
**{
|
1539
|
-
'访客数': ('访客数', np.max),
|
1540
|
-
'加购人数': ('加购人数', np.max),
|
1541
|
-
'支付金额': ('支付金额', np.max),
|
1542
|
-
'支付转化率': ('支付转化率', np.max),
|
1543
|
-
'支付买家数': ('支付买家数', np.max),
|
1544
|
-
'客单价': ('客单价', np.max),
|
1545
|
-
'uv价值': ('uv价值', np.max)
|
1546
|
-
}
|
1547
|
-
)
|
1548
|
-
return df
|
1549
|
-
elif '生意参谋_直播场次分析' in table_name:
|
1550
|
-
df.drop_duplicates(subset=['场次id'], keep='first', inplace=True, ignore_index=True)
|
1551
|
-
return df
|
1552
|
-
elif '多店推广场景_按日聚合' in table_name:
|
1553
|
-
df['日期'] = pd.to_datetime(df['日期'], format='%Y-%m-%d', errors='ignore') # 转换日期列
|
1554
|
-
df = df.groupby(
|
1555
|
-
['日期', '店铺名称', '营销场景'],
|
1556
|
-
as_index=False).agg(
|
1557
|
-
**{
|
1558
|
-
'花费': ('花费', np.sum),
|
1559
|
-
'展现量': ('展现量', np.sum),
|
1560
|
-
'点击量': ('点击量', np.sum),
|
1561
|
-
'加购量': ('加购量', np.sum),
|
1562
|
-
'成交笔数': ('成交笔数', np.sum),
|
1563
|
-
'成交金额': ('成交金额', np.sum)
|
1564
|
-
}
|
1565
|
-
)
|
1566
|
-
df.sort_values(['日期', '店铺名称', '花费'], ascending=[False, False, False], ignore_index=True, inplace=True)
|
1567
|
-
# df.to_csv('/Users/xigua/Downloads/test.csv', encoding='utf-8_sig', index=False, header=True)
|
1568
|
-
return df
|
1569
|
-
elif '达摩盘_人群报表' in table_name:
|
1570
|
-
return df
|
1571
|
-
|
1572
|
-
else:
|
1573
|
-
print(f'<{table_name}>: Groupby 类尚未配置,数据为空')
|
1574
|
-
return pd.DataFrame({})
|
2019
|
+
set_typ = {
|
2020
|
+
'店铺名称': 'varchar(100)',
|
2021
|
+
'日期': 'date',
|
2022
|
+
'人群id': 'bigint',
|
2023
|
+
'人群名称': 'varchar(255)',
|
2024
|
+
'营销渠道': 'varchar(100)',
|
2025
|
+
'计划基础信息': 'varchar(255)',
|
2026
|
+
'推广单元信息': 'varchar(255)',
|
2027
|
+
'消耗_元': 'decimal(10,2)',
|
2028
|
+
'展现人数': 'int',
|
2029
|
+
'展现量': 'int',
|
2030
|
+
'点击人数': 'int',
|
2031
|
+
'点击量': 'int',
|
2032
|
+
'店铺收藏人数': 'smallint',
|
2033
|
+
'店铺收藏量': 'smallint',
|
2034
|
+
'加购人数': 'smallint',
|
2035
|
+
'加购量': 'smallint',
|
2036
|
+
'宝贝收藏人数': 'smallint',
|
2037
|
+
'宝贝收藏量': 'smallint',
|
2038
|
+
'收藏加购量': 'smallint',
|
2039
|
+
'收藏加购人数': 'smallint',
|
2040
|
+
'拍下人数': 'smallint',
|
2041
|
+
'拍下订单量': 'smallint',
|
2042
|
+
'拍下订单金额_元': 'decimal(10,2)',
|
2043
|
+
'成交人数': 'smallint',
|
2044
|
+
'成交订单量': 'smallint',
|
2045
|
+
'成交订单金额_元': 'decimal(10,2)',
|
2046
|
+
'店铺首购人数': 'smallint',
|
2047
|
+
'店铺复购人数': 'smallint',
|
2048
|
+
'点击率': 'decimal(10,4)',
|
2049
|
+
'uv点击率': 'decimal(10, 4)',
|
2050
|
+
'收藏加购率': 'decimal(10, 4)',
|
2051
|
+
'uv收藏加购率': 'decimal(10, 4)',
|
2052
|
+
'点击转化率': 'decimal(10, 4)',
|
2053
|
+
'uv点击转化率': 'decimal(10, 4)',
|
2054
|
+
'投资回报率': 'decimal(10, 4)',
|
2055
|
+
'千次展现成本_元': 'decimal(10, 2)',
|
2056
|
+
'点击成本_元': 'decimal(10, 2)',
|
2057
|
+
'uv点击成本_元': 'decimal(10, 2)',
|
2058
|
+
'收藏加购成本_元': 'decimal(10, 2)',
|
2059
|
+
'uv收藏加购成本_元': 'decimal(10, 2)',
|
2060
|
+
'更新时间': 'timestamp',
|
2061
|
+
'人群规模': 'int',
|
2062
|
+
'用户年龄': 'varchar(100)',
|
2063
|
+
'消费能力等级': 'varchar(100)',
|
2064
|
+
'用户性别': 'varchar(100)',
|
2065
|
+
}
|
2066
|
+
min_date = df['日期'].min()
|
2067
|
+
max_date = df['日期'].max()
|
2068
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
2069
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
2070
|
+
m_engine.df_to_mysql(
|
2071
|
+
df=df,
|
2072
|
+
db_name=db_name,
|
2073
|
+
table_name=table_name,
|
2074
|
+
icm_update=[], # 增量更新, 在聚合数据中使用,其他不要用
|
2075
|
+
move_insert=False, # 先删除,再插入
|
2076
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
2077
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
2078
|
+
count=None,
|
2079
|
+
filename=None, # 用来追踪处理进度
|
2080
|
+
reset_id=False, # 是否重置自增列
|
2081
|
+
set_typ=set_typ,
|
2082
|
+
)
|
2083
|
+
return True
|
1575
2084
|
|
1576
2085
|
@try_except
|
1577
2086
|
def ret_keyword(self, keyword, as_file=False):
|
@@ -1876,33 +2385,77 @@ class GroupBy:
|
|
1876
2385
|
return result
|
1877
2386
|
|
1878
2387
|
# @try_except
|
1879
|
-
def performance(self, bb_tg=True):
|
1880
|
-
|
1881
|
-
tg
|
1882
|
-
|
1883
|
-
|
1884
|
-
|
1885
|
-
|
1886
|
-
|
1887
|
-
pic['商品id'] = pic['商品id'].astype(str)
|
1888
|
-
|
1889
|
-
df =
|
1890
|
-
df =
|
1891
|
-
|
1892
|
-
df = pd.merge(
|
1893
|
-
df
|
2388
|
+
def performance(self, db_name, table_name, bb_tg=True):
|
2389
|
+
|
2390
|
+
tg= [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '天猫_主体报表'][0]
|
2391
|
+
syj = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '生意经_宝贝指标'][0]
|
2392
|
+
idbm = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '商品id编码表'][0]
|
2393
|
+
pic = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '商品id图片对照表'][0]
|
2394
|
+
cost = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '商品成本'][0]
|
2395
|
+
|
2396
|
+
# pic['商品id'] = pic['商品id'].astype(str)
|
2397
|
+
# # 1. id 编码表合并图片表
|
2398
|
+
# df = pd.merge(idbm, pic, how='left', left_on='宝贝id', right_on='商品id')
|
2399
|
+
# df = df[['宝贝id', '商家编码', '商品图片']]
|
2400
|
+
# # 2. df 合并商品成本表
|
2401
|
+
# df = pd.merge(df, cost, how='left', left_on='商家编码', right_on='款号')
|
2402
|
+
# df = df[['宝贝id', '商家编码', '商品图片', '成本价']]
|
2403
|
+
# # 3. 推广表合并 df
|
2404
|
+
# df = pd.merge(tg, df, how='left', left_on='商品id', right_on='宝贝id')
|
2405
|
+
# df.drop(labels='宝贝id', axis=1, inplace=True)
|
2406
|
+
|
2407
|
+
# 由于推广表之前根据场景、营销渠道等聚合的,这里不含这些字段所以要进一步聚合
|
2408
|
+
tg = tg.groupby(
|
2409
|
+
['日期', '店铺名称', '商品id'],
|
2410
|
+
as_index=False).agg(
|
2411
|
+
**{
|
2412
|
+
'花费': ('花费', np.sum),
|
2413
|
+
'成交金额': ('成交金额', np.sum),
|
2414
|
+
'直接成交金额': ('直接成交金额', np.sum),
|
2415
|
+
}
|
2416
|
+
)
|
2417
|
+
syj.to_csv('/Users/xigua/Downloads/ddd.csv', index=False, header=True, encoding='utf-8_sig')
|
2418
|
+
# 4. 生意经,推广表聚合
|
1894
2419
|
if bb_tg is True:
|
1895
2420
|
# 生意经合并推广表,完整的数据表,包含全店所有推广、销售数据
|
1896
|
-
df = pd.merge(syj,
|
2421
|
+
df = pd.merge(syj, tg, how='left', left_on=['日期', '店铺名称', '宝贝id'], right_on=['日期', '店铺名称', '商品id'])
|
1897
2422
|
df.drop(labels='商品id', axis=1, inplace=True) # 因为生意经中的宝贝 id 列才是完整的
|
1898
2423
|
df.rename(columns={'宝贝id': '商品id'}, inplace=True)
|
1899
|
-
# df.to_csv('/Users/xigua/Downloads/test.csv', encoding='utf-8_sig', index=False, header=True)
|
1900
2424
|
else:
|
1901
2425
|
# 推广表合并生意经 , 以推广数据为基准,销售数据不齐全
|
1902
|
-
df = pd.merge(
|
2426
|
+
df = pd.merge(tg, syj, how='left', left_on=['日期', '店铺名称', '商品id'], right_on=['日期', '店铺名称', '宝贝id'])
|
1903
2427
|
df.drop(labels='宝贝id', axis=1, inplace=True)
|
1904
|
-
|
1905
|
-
df.
|
2428
|
+
|
2429
|
+
df['商品id'] = df['商品id'].astype(int)
|
2430
|
+
df = df.groupby(
|
2431
|
+
['日期', '店铺名称', '商品id'],
|
2432
|
+
as_index=False).agg(
|
2433
|
+
**{
|
2434
|
+
'花费': ('花费', np.sum),
|
2435
|
+
'成交金额': ('成交金额', np.sum),
|
2436
|
+
'直接成交金额': ('直接成交金额', np.sum),
|
2437
|
+
'销售额': ('销售额', np.sum),
|
2438
|
+
'销售量': ('销售量', np.sum),
|
2439
|
+
'退款额_发货后': ('退款额_发货后', np.sum),
|
2440
|
+
'退货量_发货后': ('退货量_发货后', np.sum),
|
2441
|
+
}
|
2442
|
+
)
|
2443
|
+
# print(df.info())
|
2444
|
+
|
2445
|
+
idbm['宝贝id'] = idbm['宝贝id'].astype(int)
|
2446
|
+
# 1. id 编码表合并图片表
|
2447
|
+
df_cb = pd.merge(idbm, pic, how='left', left_on='宝贝id', right_on='商品id')
|
2448
|
+
df_cb = df_cb[['宝贝id', '商家编码', '商品图片']]
|
2449
|
+
# 2. df 合并商品成本表
|
2450
|
+
df_cb = pd.merge(df_cb, cost, how='left', left_on='商家编码', right_on='款号')
|
2451
|
+
df_cb = df_cb[['宝贝id', '商家编码', '商品图片', '成本价']]
|
2452
|
+
# print(df_cb.info())
|
2453
|
+
# 3. 合并 df
|
2454
|
+
df = pd.merge(df, df_cb, how='left', left_on='商品id', right_on='宝贝id')
|
2455
|
+
df.drop(labels='宝贝id', axis=1, inplace=True)
|
2456
|
+
|
2457
|
+
# df.drop_duplicates(subset=['日期', '店铺名称', '商品id', '花费', '销售额'], keep='last', inplace=True, ignore_index=True)
|
2458
|
+
# df.fillna(0, inplace=True)
|
1906
2459
|
df['成本价'] = df['成本价'].astype('float64')
|
1907
2460
|
df['销售额'] = df['销售额'].astype('float64')
|
1908
2461
|
df['销售量'] = df['销售量'].astype('int64')
|
@@ -1910,11 +2463,74 @@ class GroupBy:
|
|
1910
2463
|
df['商品毛利'] = df.apply(lambda x: x['销售额'] - x['商品成本'], axis=1)
|
1911
2464
|
df['毛利率'] = df.apply(lambda x: round((x['销售额'] - x['商品成本']) / x['销售额'], 4) if x['销售额'] > 0 else 0, axis=1)
|
1912
2465
|
df['盈亏'] = df.apply(lambda x: x['商品毛利'] - x['花费'], axis=1)
|
1913
|
-
|
2466
|
+
set_typ = {
|
2467
|
+
'日期': 'date',
|
2468
|
+
'店铺名称': 'varchar(100)',
|
2469
|
+
'商品id': 'bigint',
|
2470
|
+
'销售额': 'decimal(12,2)',
|
2471
|
+
'销售量': 'int',
|
2472
|
+
'退款额_发货后': 'decimal(12,2)',
|
2473
|
+
'退货量_发货后': 'int',
|
2474
|
+
'花费': 'decimal(12,2)',
|
2475
|
+
'成交金额': 'decimal(12,2)',
|
2476
|
+
'直接成交金额': 'decimal(12,2)',
|
2477
|
+
'商家编码': 'varchar(100)',
|
2478
|
+
'商品图片': 'varchar(255)',
|
2479
|
+
'成本价': 'decimal(10,2)',
|
2480
|
+
'商品成本': 'decimal(10,2)',
|
2481
|
+
'商品毛利': 'decimal(10,2)',
|
2482
|
+
'毛利率': 'decimal(12,4)',
|
2483
|
+
'盈亏': 'decimal(12,4)',
|
2484
|
+
}
|
2485
|
+
if not self.update_service:
|
2486
|
+
return
|
2487
|
+
min_date = df['日期'].min()
|
2488
|
+
max_date = df['日期'].max()
|
2489
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
2490
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
2491
|
+
m_engine.df_to_mysql(
|
2492
|
+
df=df,
|
2493
|
+
db_name=db_name,
|
2494
|
+
table_name=table_name,
|
2495
|
+
icm_update=[], # 增量更新, 在聚合数据中使用,其他不要用
|
2496
|
+
move_insert=True, # 先删除,再插入
|
2497
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
2498
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
2499
|
+
count=None,
|
2500
|
+
filename=None, # 用来追踪处理进度
|
2501
|
+
reset_id=False, # 是否重置自增列
|
2502
|
+
set_typ=set_typ,
|
2503
|
+
)
|
2504
|
+
return True
|
2505
|
+
|
2506
|
+
# @try_except
|
2507
|
+
def performance_concat(self, db_name, table_name, bb_tg=True):
|
2508
|
+
tg = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '天猫汇总表调用'][0]
|
2509
|
+
zb = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '天猫_超级直播'][0]
|
2510
|
+
pxb = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '天猫_品销宝账户报表'][0]
|
2511
|
+
zb = zb.groupby(['日期', '店铺名称', '推广渠道', '营销场景'], as_index=False).agg(
|
2512
|
+
**{
|
2513
|
+
'花费': ('花费', np.sum),
|
2514
|
+
'展现量': ('展现量', np.sum),
|
2515
|
+
'观看次数': ('观看次数', np.sum),
|
2516
|
+
'加购量': ('加购量', np.sum),
|
2517
|
+
'成交笔数': ('成交笔数', np.sum),
|
2518
|
+
'成交金额': ('成交金额', np.sum),
|
2519
|
+
'直接成交笔数': ('直接成交笔数', np.sum),
|
2520
|
+
'直接成交金额': ('直接成交金额', np.sum),
|
2521
|
+
}
|
2522
|
+
)
|
2523
|
+
pxb = pxb.groupby(['日期', '店铺名称', '推广渠道', '营销场景'], as_index=False).agg(
|
2524
|
+
**{
|
2525
|
+
'花费': ('花费', np.sum),
|
2526
|
+
'展现量': ('展现量', np.sum),
|
2527
|
+
'点击量': ('点击量', np.sum),
|
2528
|
+
'加购量': ('加购量', np.sum),
|
2529
|
+
'成交笔数': ('成交笔数', np.sum),
|
2530
|
+
'成交金额': ('成交金额', np.sum)
|
2531
|
+
}
|
2532
|
+
)
|
1914
2533
|
|
1915
|
-
@try_except
|
1916
|
-
def performance_concat(self, bb_tg=True):
|
1917
|
-
tg, zb, pxb = self.data_tgyj['天猫汇总表调用'], self.data_tgyj['天猫_超级直播'], self.data_tgyj['天猫_品销宝账户报表']
|
1918
2534
|
zb.rename(columns={
|
1919
2535
|
'观看次数': '点击量',
|
1920
2536
|
}, inplace=True)
|
@@ -1959,23 +2575,61 @@ class GroupBy:
|
|
1959
2575
|
'自然流量曝光量': int,
|
1960
2576
|
}
|
1961
2577
|
)
|
1962
|
-
|
2578
|
+
set_typ = {
|
2579
|
+
'日期': 'date',
|
2580
|
+
'店铺名称': 'varchar(100)',
|
2581
|
+
'推广渠道': 'varchar(100)',
|
2582
|
+
'营销场景': 'varchar(100)',
|
2583
|
+
'商品id': 'bigint',
|
2584
|
+
'花费': 'decimal(12,2)',
|
2585
|
+
'展现量': 'int',
|
2586
|
+
'点击量': 'int',
|
2587
|
+
'加购量': 'int',
|
2588
|
+
'成交笔数': 'int',
|
2589
|
+
'成交金额': 'decimal(12,2)',
|
2590
|
+
'直接成交笔数': 'int',
|
2591
|
+
'直接成交金额': 'decimal(12,2)',
|
2592
|
+
'自然流量曝光量': 'int',
|
2593
|
+
}
|
2594
|
+
if not self.update_service:
|
2595
|
+
return
|
2596
|
+
min_date = df['日期'].min()
|
2597
|
+
max_date = df['日期'].max()
|
2598
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
2599
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
2600
|
+
m_engine.df_to_mysql(
|
2601
|
+
df=df,
|
2602
|
+
db_name=db_name,
|
2603
|
+
table_name=table_name,
|
2604
|
+
icm_update=[], # 增量更新, 在聚合数据中使用,其他不要用
|
2605
|
+
move_insert=True, # 先删除,再插入
|
2606
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
2607
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
2608
|
+
count=None,
|
2609
|
+
filename=None, # 用来追踪处理进度
|
2610
|
+
reset_id=False, # 是否重置自增列
|
2611
|
+
set_typ=set_typ,
|
2612
|
+
)
|
2613
|
+
return True
|
1963
2614
|
|
1964
2615
|
# @try_except
|
1965
|
-
def performance_jd(self, jd_tg=True):
|
1966
|
-
jdtg
|
2616
|
+
def performance_jd(self, db_name, table_name, jd_tg=True, ):
|
2617
|
+
jdtg = [item['数据主体'] for item in self.pf_datas_jd if item['集合名称'] == '京东_京准通'][0]
|
2618
|
+
sku_sales = [item['数据主体'] for item in self.pf_datas_jd if item['集合名称'] == '京东_sku_商品明细'][0]
|
2619
|
+
cost = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '商品成本'][0]
|
2620
|
+
|
1967
2621
|
jdtg = jdtg.groupby(['日期', '跟单sku_id'],
|
1968
2622
|
as_index=False).agg(
|
1969
2623
|
**{
|
1970
2624
|
'花费': ('花费', np.sum)
|
1971
2625
|
}
|
1972
2626
|
)
|
1973
|
-
cost = self.data_tgyj['商品成本']
|
1974
2627
|
df = pd.merge(sku_sales, cost, how='left', left_on='货号', right_on='款号')
|
1975
2628
|
df = df[['日期', '商品id', '货号', '成交单量', '成交金额', '成本价']]
|
1976
2629
|
df['商品id'] = df['商品id'].astype(str)
|
1977
2630
|
jdtg['跟单sku_id'] = jdtg['跟单sku_id'].astype(str)
|
1978
2631
|
jdtg = jdtg.astype({'日期': 'datetime64[ns]'}, errors='raise')
|
2632
|
+
df = df.astype({'日期': 'datetime64[ns]'}, errors='raise')
|
1979
2633
|
if jd_tg is True:
|
1980
2634
|
# 完整的数据表,包含全店所有推广、销售数据
|
1981
2635
|
df = pd.merge(df, jdtg, how='left', left_on=['日期', '商品id'], right_on=['日期', '跟单sku_id']) # df 合并推广表
|
@@ -1994,89 +2648,40 @@ class GroupBy:
|
|
1994
2648
|
df['毛利率'] = df.apply(
|
1995
2649
|
lambda x: round((x['成交金额'] - x['商品成本']) / x['成交金额'], 4) if x['成交金额'] > 0 else 0, axis=1)
|
1996
2650
|
df['盈亏'] = df.apply(lambda x: x['商品毛利'] - x['花费'], axis=1)
|
1997
|
-
|
1998
|
-
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
2011
|
-
|
2012
|
-
path = os.path.join(self.output, path)
|
2013
|
-
if not os.path.exists(path):
|
2014
|
-
os.makedirs(path)
|
2015
|
-
if filename.endswith('.csv'):
|
2016
|
-
filename = filename[:-4]
|
2017
|
-
if st_ascend and ascend:
|
2018
|
-
try:
|
2019
|
-
df.sort_values(st_ascend, ascending=ascend, ignore_index=True, inplace=True)
|
2020
|
-
except:
|
2021
|
-
print(f'{filename}: sort_values排序参数错误!')
|
2022
|
-
if freq:
|
2023
|
-
if '日期' not in df.columns.tolist():
|
2024
|
-
return print(f'{filename}: 数据缺少日期列,无法按日期分组')
|
2025
|
-
groups = df.groupby(pd.Grouper(key='日期', freq=freq))
|
2026
|
-
for name1, df in groups:
|
2027
|
-
if freq == 'M':
|
2028
|
-
sheet_name = name1.strftime('%Y-%m')
|
2029
|
-
elif freq == 'Y':
|
2030
|
-
sheet_name = name1.strftime('%Y年')
|
2031
|
-
else:
|
2032
|
-
sheet_name = '_未分类'
|
2033
|
-
new_path = os.path.join(path, filename)
|
2034
|
-
if not os.path.exists(new_path):
|
2035
|
-
os.makedirs(new_path)
|
2036
|
-
new_path = os.path.join(new_path, f'{filename}{sheet_name}.csv')
|
2037
|
-
if st_ascend and ascend: # 这里需要重新排序一次,原因未知
|
2038
|
-
try:
|
2039
|
-
df.sort_values(st_ascend, ascending=ascend, ignore_index=True, inplace=True)
|
2040
|
-
except:
|
2041
|
-
print(f'{filename}: sort_values排序参数错误!')
|
2042
|
-
|
2043
|
-
df.to_csv(new_path, encoding=encoding, index=index, header=header)
|
2044
|
-
else:
|
2045
|
-
df.to_csv(os.path.join(path, filename + '.csv'), encoding=encoding, index=index, header=header)
|
2046
|
-
|
2047
|
-
def as_json(self, df, filename, path=None, orient='records', force_ascii=False, st_ascend=None, ascend=None):
|
2048
|
-
if len(df) == 0:
|
2049
|
-
return
|
2050
|
-
if not path:
|
2051
|
-
path = self.output
|
2052
|
-
else:
|
2053
|
-
path = os.path.join(self.output, path)
|
2054
|
-
if not os.path.exists(path):
|
2055
|
-
os.makedirs(path)
|
2056
|
-
if st_ascend and ascend:
|
2057
|
-
try:
|
2058
|
-
df.sort_values(st_ascend, ascending=ascend, ignore_index=True, inplace=True)
|
2059
|
-
except:
|
2060
|
-
print(f'{filename}: sort_values排序参数错误!')
|
2061
|
-
df.to_json(os.path.join(path, filename + '.json'),
|
2062
|
-
orient=orient, force_ascii=force_ascii)
|
2063
|
-
|
2064
|
-
def as_excel(self, df, filename, path=None, index=False, header=True, engine='openpyxl',
|
2065
|
-
freeze_panes=(1, 0), st_ascend=None, ascend=None):
|
2066
|
-
if len(df) == 0:
|
2651
|
+
# print(df.info())
|
2652
|
+
set_typ = {
|
2653
|
+
'日期': 'date',
|
2654
|
+
'跟单sku_id': 'bigint',
|
2655
|
+
'花费': 'decimal(12,2)',
|
2656
|
+
'货号': 'varchar(100)',
|
2657
|
+
'成交单量': 'int',
|
2658
|
+
'成交金额': 'decimal(12,2)',
|
2659
|
+
'成本价': 'decimal(10,2)',
|
2660
|
+
'商品成本': 'decimal(10,2)',
|
2661
|
+
'商品毛利': 'decimal(10,2)',
|
2662
|
+
'毛利率': 'decimal(12,4)',
|
2663
|
+
'盈亏': 'decimal(12,4)',
|
2664
|
+
}
|
2665
|
+
if not self.update_service:
|
2067
2666
|
return
|
2068
|
-
|
2069
|
-
|
2070
|
-
|
2071
|
-
|
2072
|
-
|
2073
|
-
|
2074
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2079
|
-
|
2667
|
+
min_date = df['日期'].min()
|
2668
|
+
max_date = df['日期'].max()
|
2669
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
2670
|
+
print(f'{now} 正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
|
2671
|
+
m_engine.df_to_mysql(
|
2672
|
+
df=df,
|
2673
|
+
db_name=db_name,
|
2674
|
+
table_name=table_name,
|
2675
|
+
icm_update=[], # 增量更新, 在聚合数据中使用,其他不要用
|
2676
|
+
move_insert=True, # 先删除,再插入
|
2677
|
+
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
2678
|
+
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
2679
|
+
count=None,
|
2680
|
+
filename=None, # 用来追踪处理进度
|
2681
|
+
reset_id=False, # 是否重置自增列
|
2682
|
+
set_typ=set_typ,
|
2683
|
+
)
|
2684
|
+
return True
|
2080
2685
|
|
2081
2686
|
|
2082
2687
|
def date_table():
|
@@ -2125,253 +2730,6 @@ def date_table():
|
|
2125
2730
|
)
|
2126
2731
|
|
2127
2732
|
|
2128
|
-
def data_aggregation(months=1, is_juhe=True, less_dict=[]):
|
2129
|
-
"""
|
2130
|
-
1. 从数据库中读取数据
|
2131
|
-
2. 数据聚合清洗
|
2132
|
-
3. 统一回传数据库: <聚合数据> (不再导出为文件)
|
2133
|
-
公司台式机调用
|
2134
|
-
months: 1+,写 0 表示当月数据,但在每月 1 号时可能会因为返回空数据出错
|
2135
|
-
is_juhe: 聚合数据
|
2136
|
-
less_dict::只聚合某个特定的库
|
2137
|
-
"""
|
2138
|
-
if months == 0:
|
2139
|
-
print(f'months 不建议为 0 ')
|
2140
|
-
return
|
2141
|
-
|
2142
|
-
sdq = MysqlDatasQuery() # 实例化数据处理类
|
2143
|
-
sdq.months = months # 设置数据周期, 1 表示近 2 个月
|
2144
|
-
g = GroupBy() # 实例化数据聚合类
|
2145
|
-
# 实例化数据库连接
|
2146
|
-
|
2147
|
-
m = mysql.MysqlUpload(username=username, password=password, host=host, port=port)
|
2148
|
-
|
2149
|
-
# 从数据库中获取数据, 返回包含 df 数据的字典
|
2150
|
-
data_dict = [
|
2151
|
-
{
|
2152
|
-
'数据库名': '聚合数据', # 清洗完回传的目的地数据库
|
2153
|
-
'集合名': '天猫_主体报表', # 清洗完回传的数据表名
|
2154
|
-
'唯一主键': ['日期', '推广渠道', '营销场景', '商品id', '花费'],
|
2155
|
-
'数据主体': sdq.tg_wxt(),
|
2156
|
-
},
|
2157
|
-
{
|
2158
|
-
'数据库名': '聚合数据',
|
2159
|
-
'集合名': '生意经_宝贝指标',
|
2160
|
-
'唯一主键': ['日期', '宝贝id'], # 不能加其他字段做主键,比如销售额,是变动的,不是唯一的
|
2161
|
-
'数据主体': sdq.syj(),
|
2162
|
-
},
|
2163
|
-
{
|
2164
|
-
'数据库名': '聚合数据',
|
2165
|
-
'集合名': '店铺流量来源构成',
|
2166
|
-
'唯一主键': ['日期', '一级来源', '二级来源', '三级来源', '访客数'],
|
2167
|
-
'数据主体': sdq.dplyd(),
|
2168
|
-
},
|
2169
|
-
{
|
2170
|
-
'数据库名': '聚合数据',
|
2171
|
-
'集合名': '商品id编码表',
|
2172
|
-
'唯一主键': ['宝贝id'],
|
2173
|
-
'数据主体': sdq.idbm(),
|
2174
|
-
},
|
2175
|
-
{
|
2176
|
-
'数据库名': '聚合数据',
|
2177
|
-
'集合名': '商品id图片对照表',
|
2178
|
-
'唯一主键': ['商品id'],
|
2179
|
-
'数据主体': sdq.sp_picture(),
|
2180
|
-
},
|
2181
|
-
{
|
2182
|
-
'数据库名': '聚合数据',
|
2183
|
-
'集合名': '商品成本', # 暂缺 10.31
|
2184
|
-
'唯一主键': ['款号'],
|
2185
|
-
'数据主体': sdq.sp_cost(),
|
2186
|
-
},
|
2187
|
-
{
|
2188
|
-
'数据库名': '聚合数据',
|
2189
|
-
'集合名': '京东_京准通',
|
2190
|
-
'唯一主键': ['日期', '产品线', '触发sku_id', '跟单sku_id', '花费', ],
|
2191
|
-
'数据主体': sdq.jdjzt(),
|
2192
|
-
},
|
2193
|
-
{
|
2194
|
-
'数据库名': '聚合数据',
|
2195
|
-
'集合名': '京东_京准通_全站营销', # 暂缺
|
2196
|
-
'唯一主键': ['日期', '产品线', '花费'],
|
2197
|
-
'数据主体': sdq.jdqzyx(),
|
2198
|
-
},
|
2199
|
-
{
|
2200
|
-
'数据库名': '聚合数据',
|
2201
|
-
'集合名': '京东_sku_商品明细',
|
2202
|
-
'唯一主键': ['日期', '商品id', '成交单量'],
|
2203
|
-
'数据主体': sdq.sku_sales(),
|
2204
|
-
},
|
2205
|
-
{
|
2206
|
-
'数据库名': '聚合数据',
|
2207
|
-
'集合名': '京东_spu_商品明细',
|
2208
|
-
'唯一主键': ['日期', '商品id', '成交单量'],
|
2209
|
-
'数据主体': sdq.spu_sales(),
|
2210
|
-
},
|
2211
|
-
{
|
2212
|
-
'数据库名': '聚合数据',
|
2213
|
-
'集合名': '天猫_人群报表',
|
2214
|
-
'唯一主键': ['日期', '推广渠道', '营销场景', '商品id', '花费', '人群名字'],
|
2215
|
-
'数据主体': sdq.tg_rqbb(),
|
2216
|
-
},
|
2217
|
-
{
|
2218
|
-
'数据库名': '聚合数据',
|
2219
|
-
'集合名': '天猫_关键词报表',
|
2220
|
-
'唯一主键': ['日期', '推广渠道', '营销场景', '商品id', '花费', '词类型', '词名字_词包名字',],
|
2221
|
-
'数据主体': sdq.tg_gjc(),
|
2222
|
-
},
|
2223
|
-
{
|
2224
|
-
'数据库名': '聚合数据',
|
2225
|
-
'集合名': '天猫_超级直播',
|
2226
|
-
'唯一主键': ['日期', '推广渠道', '营销场景', '花费'],
|
2227
|
-
'数据主体': sdq.tg_cjzb(),
|
2228
|
-
},
|
2229
|
-
{
|
2230
|
-
'数据库名': '聚合数据',
|
2231
|
-
'集合名': '京东_关键词报表',
|
2232
|
-
'唯一主键': ['日期', '产品线', '搜索词', '关键词', '展现数', '花费'],
|
2233
|
-
'数据主体': sdq.jd_gjc(),
|
2234
|
-
},
|
2235
|
-
{
|
2236
|
-
'数据库名': '聚合数据',
|
2237
|
-
'集合名': '天猫_品销宝账户报表',
|
2238
|
-
'唯一主键': ['日期', '报表类型', '推广渠道', '营销场景', '花费'],
|
2239
|
-
'数据主体': sdq.pxb_zh(),
|
2240
|
-
},
|
2241
|
-
{
|
2242
|
-
'数据库名': '聚合数据',
|
2243
|
-
'集合名': '天猫店铺来源_手淘搜索', # 暂缺
|
2244
|
-
'唯一主键': ['日期', '关键词', '访客数'],
|
2245
|
-
'数据主体': sdq.se_search(),
|
2246
|
-
},
|
2247
|
-
{
|
2248
|
-
'数据库名': '聚合数据',
|
2249
|
-
'集合名': '生意参谋_直播场次分析', # 暂缺
|
2250
|
-
'唯一主键': ['场次id'],
|
2251
|
-
'数据主体': sdq.zb_ccfx(),
|
2252
|
-
},
|
2253
|
-
{
|
2254
|
-
'数据库名': '聚合数据',
|
2255
|
-
'集合名': '多店推广场景_按日聚合',
|
2256
|
-
'唯一主键': [],
|
2257
|
-
'数据主体': sdq.tg_by_day(),
|
2258
|
-
},
|
2259
|
-
{
|
2260
|
-
'数据库名': '聚合数据',
|
2261
|
-
'集合名': '爱库存_商品spu榜单',
|
2262
|
-
'唯一主键': [],
|
2263
|
-
'数据主体': sdq.aikucun_bd_spu(),
|
2264
|
-
},
|
2265
|
-
{
|
2266
|
-
'数据库名': '聚合数据',
|
2267
|
-
'集合名': '达摩盘_人群报表',
|
2268
|
-
'唯一主键': [],
|
2269
|
-
'数据主体': sdq.dmp_crowd(),
|
2270
|
-
},
|
2271
|
-
]
|
2272
|
-
|
2273
|
-
if less_dict:
|
2274
|
-
data_dict = [item for item in data_dict if item['集合名'] in less_dict]
|
2275
|
-
for items in data_dict: # 遍历返回结果
|
2276
|
-
db_name, table_name, unique_key_list, df = items['数据库名'], items['集合名'], items['唯一主键'], items['数据主体']
|
2277
|
-
df = g.groupby(df=df, table_name=table_name, is_maximize=True) # 2. 聚合数据
|
2278
|
-
if len(g.sp_index_datas) != 0:
|
2279
|
-
# 由推广主体报表,写入一个商品索引表,索引规则:从上月 1 号至今花费从高到低排序
|
2280
|
-
m.df_to_mysql(
|
2281
|
-
df=g.sp_index_datas,
|
2282
|
-
db_name='属性设置3',
|
2283
|
-
table_name='商品索引表_主推排序调用',
|
2284
|
-
move_insert=False, # 先删除,再插入
|
2285
|
-
# df_sql=True,
|
2286
|
-
drop_duplicates=False,
|
2287
|
-
icm_update=['商品id'],
|
2288
|
-
count=None,
|
2289
|
-
filename=None,
|
2290
|
-
set_typ={},
|
2291
|
-
)
|
2292
|
-
g.sp_index_datas = pd.DataFrame() # 重置,不然下个循环会继续刷入数据库
|
2293
|
-
# g.as_csv(df=df, filename=table_name + '.csv') # 导出 csv
|
2294
|
-
if '日期' in df.columns.tolist():
|
2295
|
-
m.df_to_mysql(
|
2296
|
-
df=df,
|
2297
|
-
db_name=db_name,
|
2298
|
-
table_name=table_name,
|
2299
|
-
move_insert=True, # 先删除,再插入
|
2300
|
-
# df_sql=True,
|
2301
|
-
# drop_duplicates=False,
|
2302
|
-
# icm_update=unique_key_list,
|
2303
|
-
count=None,
|
2304
|
-
filename=None,
|
2305
|
-
set_typ={},
|
2306
|
-
) # 3. 回传数据库
|
2307
|
-
else: # 没有日期列的就用主键排重
|
2308
|
-
m.df_to_mysql(
|
2309
|
-
df=df,
|
2310
|
-
db_name=db_name,
|
2311
|
-
table_name=table_name,
|
2312
|
-
move_insert=False, # 先删除,再插入
|
2313
|
-
# df_sql=True,
|
2314
|
-
drop_duplicates=False,
|
2315
|
-
icm_update=unique_key_list,
|
2316
|
-
count=None,
|
2317
|
-
filename=None,
|
2318
|
-
set_typ={},
|
2319
|
-
) # 3. 回传数据库
|
2320
|
-
if is_juhe:
|
2321
|
-
res = g.performance(bb_tg=True) # 盈亏表,依赖其他表,单独做
|
2322
|
-
m.df_to_mysql(
|
2323
|
-
df=res,
|
2324
|
-
db_name='聚合数据',
|
2325
|
-
table_name='_全店商品销售',
|
2326
|
-
move_insert=True, # 先删除,再插入
|
2327
|
-
# df_sql=True,
|
2328
|
-
# drop_duplicates=False,
|
2329
|
-
# icm_update=['日期', '商品id'], # 设置唯一主键
|
2330
|
-
count=None,
|
2331
|
-
filename=None,
|
2332
|
-
set_typ={},
|
2333
|
-
)
|
2334
|
-
res = g.performance(bb_tg=False) # 盈亏表,依赖其他表,单独做
|
2335
|
-
m.df_to_mysql(
|
2336
|
-
df=res,
|
2337
|
-
db_name='聚合数据',
|
2338
|
-
table_name='_推广商品销售',
|
2339
|
-
move_insert=True, # 先删除,再插入
|
2340
|
-
# df_sql=True,
|
2341
|
-
# drop_duplicates=False,
|
2342
|
-
# icm_update=['日期', '商品id'], # 设置唯一主键
|
2343
|
-
count=None,
|
2344
|
-
filename=None,
|
2345
|
-
set_typ={},
|
2346
|
-
)
|
2347
|
-
res = g.performance_concat(bb_tg=False) # 推广主体合并直播表,依赖其他表,单独做
|
2348
|
-
m.df_to_mysql(
|
2349
|
-
df=res,
|
2350
|
-
db_name='聚合数据',
|
2351
|
-
table_name='天猫_推广汇总',
|
2352
|
-
move_insert=True, # 先删除,再插入
|
2353
|
-
# df_sql=True,
|
2354
|
-
# drop_duplicates=False,
|
2355
|
-
# icm_update=['日期', '推广渠道', '营销场景', '商品id', '花费', '展现量', '点击量'], # 设置唯一主键
|
2356
|
-
count=None,
|
2357
|
-
filename=None,
|
2358
|
-
set_typ={},
|
2359
|
-
)
|
2360
|
-
res = g.performance_jd(jd_tg=False) # 盈亏表,依赖其他表,单独做
|
2361
|
-
m.df_to_mysql(
|
2362
|
-
df=res,
|
2363
|
-
db_name='聚合数据',
|
2364
|
-
table_name='_京东_推广商品销售',
|
2365
|
-
move_insert=True, # 先删除,再插入
|
2366
|
-
# df_sql=True,
|
2367
|
-
# drop_duplicates=False,
|
2368
|
-
# icm_update=['日期', '跟单sku_id', '货号', '花费'], # 设置唯一主键
|
2369
|
-
count=None,
|
2370
|
-
filename=None,
|
2371
|
-
set_typ={},
|
2372
|
-
)
|
2373
|
-
|
2374
|
-
|
2375
2733
|
def main(days=100, months=3):
|
2376
2734
|
# 1. 更新日期表 更新货品年份基准表, 属性设置 3 - 货品年份基准
|
2377
2735
|
date_table()
|
@@ -2392,11 +2750,7 @@ def main(days=100, months=3):
|
|
2392
2750
|
)
|
2393
2751
|
|
2394
2752
|
# 3. 数据聚合
|
2395
|
-
|
2396
|
-
months=months,
|
2397
|
-
is_juhe=True, # 生成聚合表
|
2398
|
-
# less_dict=['天猫_品销宝账户报表'], # 单独聚合某一个数据库
|
2399
|
-
)
|
2753
|
+
query_(months=3)
|
2400
2754
|
time.sleep(60)
|
2401
2755
|
|
2402
2756
|
# 4. 清理聚合数据
|
@@ -2408,16 +2762,41 @@ def main(days=100, months=3):
|
|
2408
2762
|
)
|
2409
2763
|
|
2410
2764
|
|
2765
|
+
def query_(months=1, less_dict=[]):
|
2766
|
+
if months == 0:
|
2767
|
+
print(f'months 不建议为 0 ')
|
2768
|
+
return
|
2769
|
+
sdq = MysqlDatasQuery() # 实例化数据处理类
|
2770
|
+
sdq.months = months # 设置数据周期, 1 表示近 2 个月
|
2771
|
+
sdq.update_service = True # 调试时加,true: 将数据写入 mysql 服务器
|
2772
|
+
|
2773
|
+
sdq.tg_wxt(db_name='聚合数据', table_name='天猫_主体报表')
|
2774
|
+
sdq.syj(db_name='聚合数据', table_name='生意经_宝贝指标')
|
2775
|
+
sdq.idbm(db_name='聚合数据', table_name='商品id编码表')
|
2776
|
+
sdq.sp_picture(db_name='聚合数据', table_name='商品id图片对照表')
|
2777
|
+
sdq.sp_cost(db_name='聚合数据', table_name='商品成本')
|
2778
|
+
sdq.dplyd(db_name='聚合数据', table_name='店铺流量来源构成')
|
2779
|
+
sdq.jdjzt(db_name='聚合数据', table_name='京东_京准通')
|
2780
|
+
sdq.jdqzyx(db_name='聚合数据', table_name='京东_京准通_全站营销')
|
2781
|
+
sdq.sku_sales(db_name='聚合数据', table_name='京东_sku_商品明细')
|
2782
|
+
sdq.spu_sales(db_name='聚合数据', table_name='京东_spu_商品明细')
|
2783
|
+
sdq.tg_rqbb(db_name='聚合数据', table_name='天猫_人群报表')
|
2784
|
+
sdq.tg_gjc(db_name='聚合数据', table_name='天猫_关键词报表')
|
2785
|
+
sdq.tg_cjzb(db_name='聚合数据', table_name='天猫_超级直播')
|
2786
|
+
sdq.jd_gjc(db_name='聚合数据', table_name='京东_关键词报表')
|
2787
|
+
sdq.pxb_zh(db_name='聚合数据', table_name='天猫_品销宝账户报表')
|
2788
|
+
sdq.se_search(db_name='聚合数据', table_name='天猫店铺来源_手淘搜索')
|
2789
|
+
sdq.zb_ccfx(db_name='聚合数据', table_name='生意参谋_直播场次分析')
|
2790
|
+
sdq.tg_by_day(db_name='聚合数据', table_name='多店推广场景_按日聚合')
|
2791
|
+
sdq.aikucun_bd_spu(db_name='聚合数据', table_name='爱库存_商品spu榜单')
|
2792
|
+
sdq.dmp_crowd(db_name='聚合数据', table_name='达摩盘_人群报表')
|
2793
|
+
sdq.performance(bb_tg=True, db_name='聚合数据', table_name='_全店商品销售') # _全店商品销售
|
2794
|
+
sdq.performance(bb_tg=False, db_name='聚合数据', table_name='_推广商品销售') # _推广商品销售
|
2795
|
+
sdq.performance_jd(jd_tg=False, db_name='聚合数据', table_name='_京东_推广商品销售') # _推广商品销售
|
2796
|
+
sdq.performance_concat(bb_tg=False, db_name='聚合数据', table_name='天猫_推广汇总') # _推广商品销售
|
2797
|
+
|
2798
|
+
|
2411
2799
|
if __name__ == '__main__':
|
2412
|
-
|
2413
|
-
|
2414
|
-
#
|
2415
|
-
# months=3,
|
2416
|
-
# is_juhe=True, # 生成聚合表
|
2417
|
-
# # less_dict=['天猫_品销宝账户报表'], # 单独聚合某一个数据库
|
2418
|
-
# )
|
2419
|
-
data_aggregation(
|
2420
|
-
months=1,
|
2421
|
-
is_juhe=True, # 生成聚合表
|
2422
|
-
# less_dict=['天猫_品销宝账户报表'], # 单独聚合某一个数据库
|
2423
|
-
)
|
2800
|
+
main(days=100, months=3)
|
2801
|
+
|
2802
|
+
# query_(months=1)
|