mdbq 0.0.8__py3-none-any.whl → 0.0.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.
@@ -1,321 +0,0 @@
1
- # -*- coding: UTF-8 –*-
2
- from mdbq.mongo import mongo
3
- from mdbq.mysql import s_query
4
- from mdbq.config import get_myconf
5
- import datetime
6
- from dateutil.relativedelta import relativedelta
7
- import pandas as pd
8
- import numpy as np
9
- import platform
10
- import getpass
11
- import json
12
- import os
13
-
14
-
15
- class MongoDatasQuery:
16
- """
17
- 从 数据库 中下载数据
18
- self.output: 数据库默认导出目录
19
- self.is_maximize: 是否最大转化数据
20
- """
21
- def __init__(self, target_service):
22
- # target_service 从哪个服务器下载数据
23
- self.months = 0 # 下载几个月数据, 0 表示当月, 1 是上月 1 号至今
24
- # 实例化一个下载类
25
- username, password, host, port = get_myconf.select_config_values(target_service=target_service, database='mongodb')
26
- self.download = mongo.DownMongo(username=username, password=password, host=host, port=port, save_path=None)
27
-
28
- def tg_wxt(self):
29
- self.download.start_date, self.download.end_date = self.months_data(num=self.months)
30
- projection = {
31
- '日期': 1,
32
- '场景名字': 1,
33
- '主体id': 1,
34
- '花费': 1,
35
- '展现量': 1,
36
- '点击量': 1,
37
- '总购物车数': 1,
38
- '总成交笔数': 1,
39
- '总成交金额': 1,
40
- '自然流量曝光量': 1,
41
- '直接成交笔数': 1,
42
- '直接成交金额': 1,
43
- }
44
- df = self.download.data_to_df(
45
- db_name='天猫数据2',
46
- collection_name='推广数据_宝贝主体报表',
47
- projection=projection,
48
- )
49
- return df
50
-
51
- @staticmethod
52
- def days_data(days, end_date=None):
53
- """ 读取近 days 天的数据 """
54
- if not end_date:
55
- end_date = datetime.datetime.now()
56
- start_date = end_date - datetime.timedelta(days=days)
57
- return pd.to_datetime(start_date), pd.to_datetime(end_date)
58
-
59
- @staticmethod
60
- def months_data(num=0, end_date=None):
61
- """ 读取近 num 个月的数据, 0 表示读取当月的数据 """
62
- if not end_date:
63
- end_date = datetime.datetime.now()
64
- start_date = end_date - relativedelta(months=num) # n 月以前的今天
65
- start_date = f'{start_date.year}-{start_date.month}-01' # 替换为 n 月以前的第一天
66
- return pd.to_datetime(start_date), pd.to_datetime(end_date)
67
-
68
-
69
- class MysqlDatasQuery:
70
- """
71
- 从数据库中下载数据
72
- """
73
- def __init__(self, target_service):
74
- # target_service 从哪个服务器下载数据
75
- self.months = 0 # 下载几个月数据, 0 表示当月, 1 是上月 1 号至今
76
- # 实例化一个下载类
77
- username, password, host, port = get_myconf.select_config_values(target_service=target_service, database='mysql')
78
- self.download = s_query.QueryDatas(username=username, password=password, host=host, port=port)
79
-
80
- def tg_wxt(self):
81
- start_date, end_date = self.months_data(num=self.months)
82
- projection = {
83
- '日期': 1,
84
- '场景名字': 1,
85
- '主体id': 1,
86
- '花费': 1,
87
- '展现量': 1,
88
- '点击量': 1,
89
- '总购物车数': 1,
90
- '总成交笔数': 1,
91
- '总成交金额': 1,
92
- '自然流量曝光量': 1,
93
- '直接成交笔数': 1,
94
- '直接成交金额': 1,
95
- }
96
- df = self.download.data_to_df(
97
- db_name='天猫数据2',
98
- tabel_name='推广数据_宝贝主体报表',
99
- start_date=start_date,
100
- end_date=end_date,
101
- projection=projection,
102
- )
103
- return df
104
-
105
- def syj(self):
106
- start_date, end_date = self.months_data(num=self.months)
107
- projection = {
108
- '日期': 1,
109
- '宝贝id': 1,
110
- '商家编码': 1,
111
- '行业类目': 1,
112
- '销售额': 1,
113
- '销售量': 1,
114
- '订单数': 1,
115
- '退货量': 1,
116
- '退款额': 1,
117
- '退货量_发货后_': 1,
118
- }
119
- df = self.download.data_to_df(
120
- db_name='生意经2',
121
- tabel_name='宝贝指标',
122
- start_date=start_date,
123
- end_date=end_date,
124
- projection=projection,
125
- )
126
- return df
127
-
128
-
129
- @staticmethod
130
- def months_data(num=0, end_date=None):
131
- """ 读取近 num 个月的数据, 0 表示读取当月的数据 """
132
- if not end_date:
133
- end_date = datetime.datetime.now()
134
- start_date = end_date - relativedelta(months=num) # n 月以前的今天
135
- start_date = f'{start_date.year}-{start_date.month}-01' # 替换为 n 月以前的第一天
136
- return pd.to_datetime(start_date), pd.to_datetime(end_date)
137
-
138
-
139
- class GroupBy:
140
- """ 数据聚合和导出 """
141
- def __init__(self):
142
- # self.output: 数据库默认导出目录
143
- if platform.system() == 'Darwin':
144
- self.output = os.path.join('/Users', getpass.getuser(), '数据中心/数据库导出')
145
- elif platform.system() == 'Windows':
146
- self.output = os.path.join('C:\\同步空间\\BaiduSyncdisk\\数据库导出')
147
- else:
148
- self.output = os.path.join('数据中心/数据库导出')
149
-
150
- def groupby(self, df, tabel_name, is_maximize=True):
151
- """
152
- self.is_maximize: 是否最大转化数据
153
- """
154
-
155
- if '宝贝主体报表' in tabel_name:
156
- df.rename(columns={
157
- '场景名字': '营销场景',
158
- '主体id': '商品id',
159
- '总购物车数': '加购量',
160
- '总成交笔数': '成交笔数',
161
- '总成交金额': '成交金额'
162
- }, inplace=True)
163
- df = df.astype({
164
- '花费': float,
165
- '展现量': int,
166
- '点击量': int,
167
- '加购量': int,
168
- '成交笔数': int,
169
- '成交金额': float,
170
- '自然流量曝光量': int,
171
- '直接成交笔数': int,
172
- '直接成交金额': float,
173
- }, errors='raise')
174
- df.fillna(0, inplace=True)
175
- if is_maximize:
176
- df = df.groupby(['日期', '营销场景', '商品id', '花费', '展现量', '点击量'], as_index=False).agg(
177
- **{'加购量': ('加购量', np.max),
178
- '成交笔数': ('成交笔数', np.max),
179
- '成交金额': ('成交金额', np.max),
180
- '自然流量曝光量': ('自然流量曝光量', np.max),
181
- '直接成交笔数': ('直接成交笔数', np.max),
182
- '直接成交金额': ('直接成交金额', np.max)
183
- }
184
- )
185
- else:
186
- df = df.groupby(['日期', '营销场景', '商品id', '花费', '展现量', '点击量'], as_index=False).agg(
187
- **{'加购量': ('加购量', np.min),
188
- '成交笔数': ('成交笔数', np.min),
189
- '成交金额': ('成交金额', np.min),
190
- '自然流量曝光量': ('自然流量曝光量', np.min),
191
- '直接成交笔数': ('直接成交笔数', np.max),
192
- '直接成交金额': ('直接成交金额', np.max)
193
- }
194
- )
195
- df.insert(loc=1, column='推广渠道', value='万相台无界版') # df中插入新列
196
- return df
197
- if '宝贝指标' in tabel_name:
198
- df.fillna(0, inplace=True)
199
- df = df[(df['销售额'] != 0) | (df['退款额'] != 0)]
200
- df = df.groupby(['日期', '宝贝id', '商家编码', '行业类目'], as_index=False).agg(
201
- **{'销售额': ('销售额', np.min),
202
- '销售量': ('销售量', np.min),
203
- '订单数': ('订单数', np.min),
204
- '退货量': ('退货量', np.max),
205
- '退款额': ('退款额', np.max),
206
- '退货量_发货后_': ('退货量_发货后_', np.max),
207
- }
208
- )
209
- df['件均价'] = df.apply(lambda x: x['销售额'] / x['销售量'] if x['销售量'] > 0 else 0, axis=1).round(
210
- 0) # 两列运算, 避免除以0
211
- df['价格带'] = df['件均价'].apply(
212
- lambda x: '2000+' if x >= 2000
213
- else '1000+' if x >= 1000
214
- else '500+' if x >= 500
215
- else '300+' if x >= 300
216
- else '300以下'
217
- )
218
- return df
219
- else:
220
- print(f'<{tabel_name}>: Groupby 类尚未配置,数据为空')
221
- return pd.DataFrame({})
222
-
223
- def as_csv(self, df, filename, path=None, encoding='utf-8_sig',
224
- index=False, header=True, st_ascend=None, ascend=None, freq=None):
225
- """
226
- path: 默认导出目录 self.output, 这个函数的 path 作为子文件夹,可以不传,
227
- st_ascend: 排序参数 ['column1', 'column2']
228
- ascend: 升降序 [True, False]
229
- freq: 将创建子文件夹并按月分类存储, freq='Y', 或 freq='M'
230
- """
231
- if len(df) == 0:
232
- return
233
- if not path:
234
- path = self.output
235
- else:
236
- path = os.path.join(self.output, path)
237
- if not os.path.exists(path):
238
- os.makedirs(path)
239
- if st_ascend and ascend:
240
- try:
241
- df.sort_values(st_ascend, ascending=ascend, ignore_index=True, inplace=True)
242
- except:
243
- print(f'{filename}: sort_values排序参数错误!')
244
- if freq:
245
- if '日期' not in df.columns.tolist():
246
- return print(f'{filename}: 数据缺少日期列,无法按日期分组')
247
- groups = df.groupby(pd.Grouper(key='日期', freq=freq))
248
- for name1, df in groups:
249
- if freq == 'M':
250
- sheet_name = name1.strftime('%Y-%m')
251
- elif freq == 'Y':
252
- sheet_name = name1.strftime('%Y年')
253
- else:
254
- sheet_name = '_未分类'
255
- new_path = os.path.join(path, filename)
256
- if not os.path.exists(new_path):
257
- os.makedirs(new_path)
258
- new_path = os.path.join(new_path, f'{filename}{sheet_name}.csv')
259
- if st_ascend and ascend: # 这里需要重新排序一次,原因未知
260
- try:
261
- df.sort_values(st_ascend, ascending=ascend, ignore_index=True, inplace=True)
262
- except:
263
- print(f'{filename}: sort_values排序参数错误!')
264
-
265
- df.to_csv(new_path, encoding=encoding, index=index, header=header)
266
- else:
267
- df.to_csv(os.path.join(path, filename + '.csv'), encoding=encoding, index=index, header=header)
268
-
269
- def as_json(self, df, filename, path=None, orient='records', force_ascii=False, st_ascend=None, ascend=None):
270
- if len(df) == 0:
271
- return
272
- if not path:
273
- path = self.output
274
- else:
275
- path = os.path.join(self.output, path)
276
- if not os.path.exists(path):
277
- os.makedirs(path)
278
- if st_ascend and ascend:
279
- try:
280
- df.sort_values(st_ascend, ascending=ascend, ignore_index=True, inplace=True)
281
- except:
282
- print(f'{filename}: sort_values排序参数错误!')
283
- df.to_json(os.path.join(path, filename + '.json'),
284
- orient=orient, force_ascii=force_ascii)
285
-
286
- def as_excel(self, df, filename, path=None, index=False, header=True, engine='openpyxl',
287
- freeze_panes=(1, 0), st_ascend=None, ascend=None):
288
- if len(df) == 0:
289
- return
290
- if not path:
291
- path = self.output
292
- else:
293
- path = os.path.join(self.output, path)
294
- if not os.path.exists(path):
295
- os.makedirs(path)
296
- if st_ascend and ascend:
297
- try:
298
- df.sort_values(st_ascend, ascending=ascend, ignore_index=True, inplace=True)
299
- except:
300
- print(f'{filename}: sort_values排序参数错误!')
301
- df.to_excel(os.path.join(path, filename + '.xlsx'),
302
- index=index, header=header, engine=engine, freeze_panes=freeze_panes)
303
-
304
-
305
- def main():
306
- sdq = MysqlDatasQuery(target_service='home_lx')
307
- sdq.months = 0
308
-
309
- # df = sdq.tg_wxt() # 从数据库中获取数据并转为 df
310
- # g = GroupBy() # 数据聚合
311
- # df = g.groupby(df=df, tabel_name='推广数据_宝贝主体报表', is_maximize=True)
312
- # g.as_csv(df=df, filename='推广数据_宝贝主体报表') # 数据导出
313
-
314
- df = sdq.syj()
315
- g = GroupBy()
316
- df = g.groupby(df=df, tabel_name='宝贝指标', is_maximize=True)
317
- g.as_csv(df=df, filename='宝贝指标')
318
-
319
-
320
- if __name__ == '__main__':
321
- main()
File without changes