请上传宽度大于 1200px,高度大于 164px 的封面图片
    调整图片尺寸与位置
    滚轮可以放大缩小图片尺寸,按住图片拖动可调整位置,多余的会自动被裁剪掉
取消
龙小马的数字化之路(uid:822297)
职业资格认证:尚未取得认证
pandas中文文档——数据结构介绍2-DataFrame
DataFrame DataFrame是一种二维数据结构(我们在基础篇中讲到过),不同的列具有不同的数据类型。你可以想象它是电子表格(比如Excel的表)、数据库表或者是Series组成的字典。DataFrame是pandas中最常用的,跟Series类似,我们也可以从不同数据类型来创建一个DataFrame。 一维ndarray字典,列表字典、字典的字典、Series字典 二维ndarray Series 结构化的ndarray 另外的DataFrame 除了给出数据参数之外,你还可以选择性的给出index(行标签)和colunmns(列标签)参数。 传递的Series字典中的index如果跟指定的DataFrame的index对应不上,那么将会在生成的DataFrame中抛弃对应不上的index部分。 如果没有指定轴标签(index和columns),那么就会根据给出的data来自动生成。 从Series字典或字典生成DataFrame 如果从多个Series来生成DataFrame,得到的结果的index将会是这几个Series的index的并集。 如果要从字典来生成DataFrame,字典是个嵌套字典,那么会首先将嵌套字典转换成Series。 如果没有指定columns,将会由字典的key排序列表生成。  d = {    'one':pd.Series(,index=list('abc')),    'two':pd.Series(,index=list('abcd')) }  pd.DataFrame(d) pd.DataFrame(d,index=list('dba')) pd.DataFrame(d,index=list('dba'),columns=) 我们可以通过index和columns属性来分别获取DataFrame的行列标签信息。 注意: 如果数据来源是字典,并且指定了columns参数,那么生成的DataFrame将会以columns中指定的值为准,而忽略字典本身的键(key) df.indexdf.columns 从ndarray字典或者是列表字典生成DataFrame 如果要从ndarray字典来创建DataFrame,那么ndarray必须具有相同的长度。如果指定index,那么index的长度也要跟ndarray的长度一致。若未指定index,那么会默认生成一个range(n)(n=len(ndarray))作为index。 d = { 'one':, 'two':}pd.DataFrame(d)pd.DataFrame(d,index=list('abcd')) 从结构化的数组或记录数组生成DataFrame 这种情况跟从字典数组生成DataFrame一样。 data = np.zeros((2,), dtype=)data = pd.DataFrame(data)pd.DataFrame(data, index=)pd.DataFrame(data, columns=) 注意: DataFrame的功能并不会像numpy的ndarray那样 从字典列表创建DataFrame data2 = pd.DataFrame(data2)pd.DataFrame(data2, index=)pd.DataFrame(data2, columns=) 从元组字典生成DataFrame 我们可以通过传递一个元组字典来生成一个多索引的DataFrame。 pd.DataFrame( { ('a','b'): {('A','B'):1,('A','C'):2}, ("a", "a"): {("A", "C"): 3, ("A", "B"): 4}, ("a", "c"): {("A", "B"): 5, ("A", "C"): 6}, ("b", "a"): {("A", "C"): 7, ("A", "B"): 8}, ("b", "b"): {("A", "D"): 9, ("A", "B"): 10} }) 从Series生成DataFrame 从Series生成DataFrame,将会生成一个index和columns跟Series一样的单列DataFrame(如果没有另外指定index和columns)。 从命名元组列表生成DataFrame 列表中的命名元组的第一个命名域决定了DataFrame的列名称。余下的命名元组将会作为行数据。如果余下的这些命名元组的某一部分的长度比第一个(作为DataFrame列的元组)要短,那么余下对应不上的列将以缺失值(NaN)补充。如果长度要比作为列的部分长,那么就会报出ValueError异常。 from collections import namedtuple # 导入命名元组包Point = namedtuple("Point", "x y")pd.DataFrame()Point3D = namedtuple("Point3D", "x y z")pd.DataFrame() 从数据类列表生成DataFrame 数据类在PEP557这里有介绍,它可以传递给DataFrame的数据构造器用以创建一个DataFrame。传递一个dataclasses列表相当于传递了一个字典列表。 请注意,列表中的所有值都应该是dataclasses,如果有其他数据类型,那么将会报TypeError错误。 from dataclasses import make_dataclassPoint = make_dataclass("Point", )pd.DataFrame() 缺失值 关于缺失值这部分会有非常多的内容。我们用np.nan来代表缺失值,来处理生成DataFrame时的缺失值。   不同的构造函数 DataFrame.from_dict DataFrame.from_dict可以接受字典组成的字典或者是数组序列组成的字典,由此生成一个DataFrame。它的使用方法跟DataFrame的构造器差不多,区别在于from_dict的orient参数的默认值为'columns'。 pd.DataFrame.from_dict(dict(), ("B", )])) 如果传递参数orient='index',那么键值会作为行标签值。这种情况下,你可以传递你需要的列名称。 pd.DataFrame.from_dict( dict(),('B',)]), orient='index', columns=) DataFrame.from_records DataFrame.from_records需要提供元组列表或者是具有结构化数据的ndarray。它跟普通的DataFrame构造器使用方法很类似。区别在于,from_records的结果索引可能是结构化数据类型的特定字段。例如: datapd.DataFrame.from_records(data, index="C") 选择、添加、删除列 DataFrame进行选择、添加、删除列的操作跟字典的处理方式很接近。 df # 获取one列df = df * df # 添加three列,让其为one列和two列的乘积df = df > 2 # 添加flag列,让其为one列的2倍df 我们可以像操作字典的删除一样操作DataFrame: del df # 删除two列three = df.pop("three") # 删除three列,并返回删除的three列值赋值给three变量 当我们添加一列等于标量值时,它会自动填充整列都等于这个值: df = "bar"df 如果我们插入一个Series,它的index与DataFrame不一致,那么Series将会被对齐匹配到DataFrame的对应index上。如果插入的Series的index跟DataFrame没有对应上的,那么会被赋值为NaN: df = dfdfdf = pd.Series(,index=list(range(4)))pd.Series(,index=list(range(4)))df 我们可以插入一个长度跟Dataframe的index长度一致的原生ndarrays。 默认地,新插入的列会放在最后一列位置。我们可以使用insert方法来在特定位置插入列: df.insert(1, "bar", df) # 我们将one列复制并命名为bar,将其插入第2列的位置 在方法链中添加新列 DataFrame可以使用assign()方法来新增多列,并且可以通过现有列来生成。 df1df1.assign(G=df1*df1,H=df1+df1) # 添加G列和H列 在上面的例子中,我们插入了一个预先计算的值列。我们还可以使用函数计算来为DataFrame添加新列。 df1.assign(I=lambda x:x**2) # 我们使用lambda函数来生成一个新列 assign方法返回的结果并不会修改原DataFrame数据,而是只返回一个数据副本。 如下图所示,虽然我们使用assign添加了一列,但是原来的df1的值并没有发生变化。 索引和选择 基本的操作如下所示: 操作 语法 结果 选择列 df Series 通过标签值选择行 df.loc Series 通过行整数索引值选择行 df.iloc Series 对行切片 df DataFrame 通过布尔索引选择行 df DataFrame 行选择返回的是索引为DataFrame列名的Series。 df.locdf.iloc 关于DataFrame的索引和选择数据会单独一章讲解。 数据对齐和计算 两个DataFrame对象进行对齐操作时,它们自动根据列名和行标签值进行对齐。生成的结果会具有这俩DataFrame对象的行和列索引的交集。 df = pd.DataFrame(np.random.randn(10, 4), columns=)df2 = pd.DataFrame(np.random.randn(7, 3), columns=)df + df2 当对一个DataFrame和Series进行操作时,默认操作时将Series的index对齐到DataFrame的列上。例如: df - df.iloc 如果DataFrame要跟标量值进行运算,那么会得到如下结果: df * 5 + 2 # 得到的结果会是df的每一个值都进行 *5+2 运算 DataFrame间的布尔操作如下所示:   转置 我们使用.T属性来获取DataFrame的转置结果,它跟ndarray的操作很类似。  df.T (本文转自简道云用户:龙小马) 编辑于 2021-9-16 15:26
pandas中文文档——数据结构介绍1-series
我们将从pandas的基本数据结构的快速简介的介绍开始,以帮助我们入门。数据结构、索引和轴标签/对齐的基本操作适用于所有对象。 我们首先导入numpy和pandas以开始我们的工作。  In : import numpy as np  In : import pandas as pd 有一个基本原则需要记住:数据对齐是一个固有的内在操作。在标签和数据之间的关联不会被打破,除非你特意要这么做。 我们先简要介绍下pandas的数据结构,然后分类别讨论pandas的所有方法和功能。 Series Series的创建 Series 是可以包含所有数据类型(整型、字符串、浮点型、python对象等)的带有标签的一维数组。行列轴标签被统称为index——索引。 下面这是创建一个Series的基本方法:  s = pd.Series(data,index=index) data 可以是下面的任意一种: python字典 numpy的ndarray 标量值(例如:5) data为ndarray 如果data是ndarray,index索引必须是跟data等长度。如果没有指定index,那么将会默认生成的数值列表。  s = pd.Series(np.random.randn(5),index=list('abcde')) s.index pd.Series(np.random.randn(5)) 注意: pandas支持非唯一值的索引。如果你试图要做一个不支持重复值的索引操作,那么将会报出异常。 (这里还有一句话,没太理解什么意思,以后再来补充) data为Python字典 可以通过Python字典来创建series  d = {'b':1,'a':0,'c':2} pd.Series(d) 注意: NaN 是pandas中标准处理缺失值的方式 data为标量值 如果data为标量值,那么index必须给出。标量值将会重复index的长度。  pd.Series(5,index=list('ABCDE')) Series与adarray的相似性 Series的操作跟ndarray非常相似,可以调用numpy的大多数函数。 但是,切片这样的操作,同时也会对索引起作用。  s s s s] np.exp(s) 注意: 我们会在索引和选择数据部分介绍数组类型的索引选择。 Series 和numpy的数组一样,可以通过dtype获取数据类型  s.dtype 如果你想把series转换成数组,可以使用series.array  s.array 尽管series与numpy的ndarray很像,但如果你想要得到真正的ndarray,可以使用series.to_numpy()  s.to_numpy() Series 与字典的相似性 Series类似于固定大小的字典,可以通过索引标签来获取值  s s s 'e' in s 'f' in s 如果调用的标签值不存在,那么就会抛出异常  s 使用get()方法,不存在的标签值调用时会返回None或者被指定的特定值  s.get('f') s.get('f',np.nan) Series的向量化操作与标签对齐 当我们处理原生numpy数组时,我们不需要循环遍历每一个值。在pandas中处理series时也同样如此。series可以继承numpy的大多数方法用以处理类似ndarray的数据。  s + s # 可以直接进行加法运算 s * 2 # 可以进行乘法运算 s * s # 可以自我相乘 np.exp(s) # 使用numpy的方法 series和ndarray的一个关键不同之处在于,series处理数据时会自动根据索引标签进行对齐。因此,在你进行series计算时你可以忽略series是否具有相同的标签。  s + s # 这俩series会自动根据彼此的索引值进行对齐计算。s是获取的倒数第2个值。这个具体在索引和选择数据篇章介绍。 两个索引标签没有对齐的series的计算结果会涉及到索引的并集运算。如果一个标签值在另外一个series中找不到,那么它对应的值会被标记为NaN(看上面例子中a和e的结果值)。 这种不需要明确的数据对齐的操作可以让我们在交互式数据分析和探索时能够非常自由和灵活的书写代码。这种特性也让pandas能够区别于市面上大多数的其他数据处理工具。 注意: 一般来说, 在处理索引标签不对齐的series的运算时,为了不丢失信息,我们会获取索引并集计算的默认结果。尽管数据被被标记为NaN,但是保留标签在运算时是非常重要的。当然,你也可以选择使用dropna删除包含NaN的索引数据。 Name方法 series有个name()方法可以为series命名  s = pd.Series(np.random.randn(5),name='随意') s s.name Series的名字在大多数情况下会被默认分配一个,特别是在获取DataFrame的一维切片时(这部分你将在下面的内容中看到)。 可以通过Series.rename()方法来为Series重命名。  s.rename('与众不同') (本文转自简道云用户:龙小马)     编辑于 2021-9-16 12:35
简道云还能做ABC分类!?
  ABC分类法是个啥?   ABC分类法又称帕累托分析法或巴雷托分析法、柏拉图分析、主次因素分析法 、ABC分析法、ABC法则、分类管理法、重点管理法、ABC管理法、abc管理、巴雷特分析法,它是根据事物在技术或经济方面的主要特征,进行分类排队,分清重点和一般,从而有区别地确定管理方式的一种分析方法。由于它把被分析的对象分成A、B、C三类,所以又称为ABC分析法。经过管理学大师——彼得·德鲁克( P.F.Drucker)将这一方法推广到全部社会现象,使ABC法成为企业提高效益的普遍应用的管理方法。   引用:https://wiki.mbalib.com/wiki/ABC%E5%88%86%E7%B1%BB%E6%B3%95 ABC分类法也许很多人并不熟悉,但是说到另外一个词,相信大家一定非常熟悉——80/20法则!   ABC法则是帕累托80/20法则衍生出来的一种法则。所不同的是,80/20法则强调的是抓住关键,ABC法则强调的是分清主次,并将管理对象划分为A、B、C三类。 ABC分类法的经典分析图是这样的 通过上图的比例分割,我们可以非常清晰的将我们的分析对象分成三部分,贡献80%的头部也就是A区,贡献15%的中部也就是B区,贡献最后5%的尾部也就是C区。   而今天我们在这里讨论的将是ABC分类法的一个在日期排列上的变形分布。 下面我们拭目以待!     简道云为何难做ABC分类? ABC分类的计算中,需要进行3部分计算: 1、对将要分析的对象进行降序排序 2、获取对象的移动累计值 3、获取移动累计值与总计值的占比 而简道云进行ABC分类计算的难点就在于获取对象的移动累计值! 移动累计值是个啥呢? 举个栗子: ABCDE这5人的业绩排名,那么A的移动累计值就是SUM(A),而B的移动累计值为SUM(A,B),C的移动累计值就是SUM(A,B,C)……以此类推。 简道云不管是工厂的计算字段还是仪表盘的计算字段,他们都做不到这个移动累计的计算,因为他们无法突破指标所在行的限制(用power bi的词来说就是无法摆脱当前行上下文的筛选)。不管是工厂还是仪表盘,他们都是对自己的数据源所形成的数据表进行的计算,每一个指标都固定在每一行数据上,你在计算当前行的数据时不能超越当前行去计算别的行。拿ABCDE的移动累计计算来说,C的计算只能汇总计算A所在行指标,它跳不出这个所在行限制而去计算A所在行和B所在行的指标汇总值。所以移动累计无法实现。 虽则如此,但针对我们今天想要实现的基于日期的分布分析,我们可以投机取巧,另辟道路去曲线救国实现它! 先给大家看看最终效果! 折线图显示的是每日的移动累计值占整月累计值的占比,它反映每天的移动累计占比情况。柱形图反应的是每日的数据。可以看出跟ABC分类法的经典分布图不太一样。上图是按照日期的升序排列的。     如何做ABC分类? 在详细展开之前,建议大家先阅读一下我之前的几篇关于工厂日期处理的文章,因为本文的基础就是之前日期处理文章中所讲到的东西! 简道云自定义日期分析满足你对日期分析的各种! 简道云数据工厂系列——日期处理篇 既然我们知道ABC分类法的重要指标——移动累计用仪表盘无法获得,那么我们就来看看针对日期升序排列的特殊分布来说,我们有什么窍门可走。 针对日期的移动累计,我们可以这样来说明: 1日的累计为<=1日的数据汇总 2日的累计为<=2日的数据汇总 3日的累计为<=3日的数据汇总 ………… N日的累计为<=N日的数据汇总 因此,我们就可以通过这个来用工厂里的筛选实现这个人工移动汇总。 下面我们一步步来分解下 第1步:连接日期表 先将明细表跟日期表进行关联,获得日期表中的数值格式的年月日(因为我们需要对日进行<=筛选;关于日期表可以参考本节介绍的两篇文章) 第2步:分日筛选 我们需要对1-31日进行筛选。如下两图所示 第3步:重定义日数值 筛选过后,我们还需要对日进行重定义。添加计算字段,重定义日为当前节点日。   第4步:横向连接日期表 将上面重新定义完日的数据再一次跟日期表横向连接以获取日期格式的日期和文本格式的日期,方便后面的汇总计算。 第5步:汇总数据 将前面得到的数据根据所需分析的维度进行分组汇总。 第6步:连接月度汇总值 在这一步里,我们需要将按月汇总得到的数据跟每日数据进行连接,用于后期的移动累计/当月汇总的计算。 第7步:连接每日数据 我们还需要对每日的汇总数据进行重连接,以保证我们得到的最终表中有每日的数据,而不仅仅有移动累计和月度累计。 第8步:字段显示与位置设置 重新调整设置下最终得到的数据表。 第9步:仪表盘移动占比计算 至此,我们的ABC分类的工厂模型和仪表盘就设计完毕了! 由图中我们可以了解到,占比的折线呈现微弱的指数形态分布,前20天才完成整月的50%,而剩下的50%是后10天完成的,甚至最后3天就完成了近20%。 所以我们可以得到这样的分类结果:1-20号为A类,我们需要重点关注这些天的完成进度情况,避免在这些天里出现业绩的延误,减少销售人员的拖延,加快业绩完成速度;20-27号为B类,这些天的业绩在提速,注意观察即可;28-31号为C类,其实这是最需要关注的,因为临近月末,不仅任务压力陡增,而且业绩完成加快,需要牵动更多的人力物力,为保证月度任务的按时完成,需要投入较大人力,并时时关注销售人员动态、心态,这时销售经理应该出现在最一线,给予销售人员以鼓励和振奋。 当然,如果每月的业绩都成如图分布,那么20号的业绩也就告诉了我们本月所能完成的业绩范围大概了!!   方法分析 这种办法仅仅是针对日排序的特殊分类的一种取巧手段,目前还没有能放之四海而皆准的实现ABC分类分析的模型设计思路。 就跟当初的同比、环比一样,还是需要官方尽快更新,上线更加强大的工厂模型设计能力和仪表盘指标计算能力! 一切皆是信息,万物源自比特! 数字化必定会深刻革命我们的办公和生活! 简道云,中小企业数字化之路的绝佳伴侣!                                                                                                                                                                                                                         (本文转自简道云用户:龙小马)   编辑于 2021-9-15 15:25
简道云数据工厂的文本处理——数据分组分析
让人喜出望外的又一次更新   不可思议!今天简道云又双叒叕更新啦! 进入7月,简道云已经4更了!这速度、这频率,真是爽啊! 不过,本来今天想聊聊刚刚更新的同比环比的功能,但是测试了下,却发现设计界面显示正常,而应用访问的浏览界面却无法显示!只能明天跟官方反馈下这个问题了,今晚就先聊聊另外一个话题——数据工厂的文本处理! 数据工厂目前的计算字段,暂时只能支持数字字段,而计算字段中的函数处理,也只支持处理数值。但是,在我们的数据处理分析的场景中,是需要用到文本处理的,比如说今天的主题:数据分组,例如成绩的优良中差,例如根据销售业绩对销售人员进行进行等级区分,等等…… 那么我们该如何做呢?   数据分组的模型设计   因为数据工厂只能处理数值,所以我们需要建立一个数值和文本的对照表,通过建立的数值参数,来实现数据工厂对于文本处理的结果! 这个思路在外面之前处理自定义日期表时,也用到过,通过数值和日期的对照(实际日期值就是数值),来实现自定义日期的转变。   整体模型设计如下:   数值文本对照表   1、首先对业绩进行汇总   2、对业绩进行分组   3、完成业绩分组和对照表的横向连接,实现数值到文本的转变 最终效果 我们可以通过明细表和饼图来展示我们的分组结果   到此,我们的数据分组就我完成了!     有了简道云,数据分析全自动!                                                                                                                                                                                                                         (本文转自简道云用户:龙小马)     编辑于 2021-9-15 15:33
用简道云数据工厂搞定期初余额期末余额
刚性的功能需求 在财务管理和出入库管理过程中,大都会涉及到期初、期末余额的计算问题,这个功能也是这些对应管理应用系统的功能刚需。 对于简道云这样的灵活方便的自由应用搭建系统来说,期初期末余额的计算更是广大用户的殷切期盼的功能,来帮助大家解决相关业务报表的数据呈现问题。 目前在简道云里实现期初期末余额的方案大都是利用函数或者智能助手去完成期初期末值的计算,但这个方案灵活性不高,如果数据发生修改则无法自动更新计算结果。 简道云的数据工厂是专门用来进行数据清洗处理的工具,我们今天尝试用数据工厂来实现对于期初期末余额的计算。 期初期末余额计算分析 期初期末余额目前之所以是个让人头疼的问题,是因为简道云目前还没有能够解决累计计算问题的好方案。在数据工厂里目前的计算字段函数只能支持单行函数,而且仅限于数值的计算(我们的方案也将基于这个数值计算特性)。而期初期末余额的计算需要使用跨行函数,与这个场景类似的还有移动累计值的计算问题。其实期初期末余额的计算问题本质上也是移动累计计算的问题。期初余额为当前期之前的累计值,期末值为包含当前期的历史累计值,本期期末余额为下期的期初余额。 既然数据工厂不支持跨行函数,那么我们只能利用现有的功能来勉强拼凑出能够实现跨行计算的能力。 首先,为了保证我们的一切计算的顺利进行,我们需要先将日期转化成数值。 上面这个日期数值对照表将帮我们来实现移动累计计算。 首先,我们把出入库明细表按照日期(年-月)进行汇总。 得到结果后计算当期净发生额 下一步,我们利用我们的日期对照表来将我们的日期维度转化成数值。 隐藏日期,保留我们连接过来的数值日期 接下来就是我们完成累计计算的重点了。(具体思路也可参考之前的文章简道云还能做ABC分类!?) 先来看看全貌的设计结果 期末余额为历史截止到本期的累计发生净值,我们先筛选数值日期≤当前数值日期的明细。 然后我们需要把筛选后的结果进行新的数值日期处理,把他们原来的日期替换成新的,以完成“累计”这个动作。 这里有个特别注意的。因为当前期的累计净值=当期期末余额=下期期初余额。所以在这里添加期初余额的对照数值日期时是本期的下期日期值。 剩下的所有日期都进行同样的处理。(这些处理就是苦逼的时候了) 处理完我们需要查看的日期查看范围之后,将他们追加合并。 接下来,我们需要将期初和期末区分开来。 然后再将它俩追加合并起来 合并之后就得到了数值日期归并的明细表了。我们接下来就是再将整个数值日期通过日期对照表逆转录成日期格式,方便我们后面的汇总、关联每期发生额以及最终的结果汇总展示。 再次按照日期年月维度汇总之后,再跟前面我们按年月汇总的每期发生额进行横向连接,获得每期发生额。(上面一步的汇总可以保证我们这里的连接时一一对应,避免出现一对多导致的数据汇总不准确) 最后处理一下我们连接得到的结果表字段。 至此,我们的整个处理过程就完成了。   结果展示   最后我们看一下我们的处理结果! 这样,我们就可以非常明了的看到每期的期初、期末余额以及当期的发生额度净值。 当然我们目前这个方法只适用于解决年、季度、月的余额计算。如果要具体到日的话,这个方法也可以,只是需要设计的节点数量就太多了,不怕累又必须的可以尝试做一下! 还是最期待官方对于这些移动累计计算场景的功能支持尽快更新!(大家一起呼吁吧!)   一切皆是信息,万物源自比特! 数字化必定会深刻革命我们的办公和生活! 简道云,中小企业数字化之路的绝佳伴侣!                                                                                                                                                                                                                                                                                   (文章来自简道云用户:龙小马)   编辑于 2021-9-15 10:37 编辑于 2021-9-15 11:02
用简道云数据工厂搭建RFM销售管理分析模型
数字化时代几乎每个销售型企业都会搭建自己的CRM系统,用来管理自己的销售机会、销售客户、销售订单等业务流程及过程中产生的所有数据。尤其是零售企业,拥有大量的自有客户的销售数据。还有电商企业,他们拥有大量的顾客浏览数据、购买数据、订单数据,这些数据如果就这么静静的躺在系统里,那么它们将毫无价值可言。 如何利用这些数据去挖掘我们的客户,哪些是我们的利润贡献客户? 哪些是我们的忠实老客户? 哪些是我们的有待挖掘其购买力的老客户? 哪些我们需要重点关注的面临流失可能的高价值顾客? 哪些是我们的新增顾客、哪些是我们的低频购买老顾客? 要想回答这些问题,首先我们需要用看得见的数据分析指标来呈现它们。正如彼得·德鲁克所言“如果你不能衡量它,你就无法增长它”。让这些静止的数据动起来,变成有生命力的有价值的信息,帮助我们实现客户增长,实现客户价值最大化,增强客户粘性,RFM模型将会帮你实现这个目标! RFM模型简介 在众多的用户价值分析模型中,RFM模型是被广泛被应用的。RFM模型是衡量客户价值和客户创利能力的重要工具和手段。该模型通过一个客户的近期购买行为、购买的总体频率以及花了多少钱三项指标来描述该客户的价值状况。 R(Recency):客户最近一次交易时间的间隔。R值越大,表示客户交易发生的日期越久,反之则表示客户交易发生的日期越近。R值越大,证明此客户沉睡时间越长,流失可能性越大。 F(Frequency):客户在最近一段时间内交易的次数。F值越大,表示客户交易越频繁,反之则表示客户交易不够活跃。F值越大的顾客也就是我们的忠实顾客,是他们活跃了我们的店面流量。而F值小的顾客,他们跟我们的粘性不大,忠诚松散,随时可能面临被竞争对手抢走的风险。 M(Monetary):客户在最近一段时间内交易的金额。M值越大,表示客户价值越高,反之则表示客户价值越低。M值越大的顾客撑起了我们的业绩,如果再利用帕累托分布分析一下,也许会发现,正是这M值大的20%的顾客,撑起了我们业绩的80%的天空! 通过将这3个维度进行简单的高低取值划分,我们可以得到下面这个三维立体模型图,共计8种分类结果。   以上内容就是对于RFM模型知识的简单介绍,如果想要了解更多内容,大家可以自行查阅资料。 RFM模型设计障碍(干货预警)   RFM模型就是要通过计算出R、F、M分别的取值,然后通过这个取值去获取所对应的客户类型。那么在这个过程中,我们需要克服哪些难题呢? “今天”这个动态值的获取 在工厂计算字段里进行日期的差值计算 RFM的具体取值设定 根据RFM的取值获取文本分类值 之所以会有这几个难题困扰着我们,是因为工厂的计算字段目前只能处理数值,也只能得到数值结果!所以无法直接处理日期值,也无法获取文本值。所以我们想要解决这个问题的关键也是在此特性之上!   划重点: 因为数据工厂目前计算字段仅仅支持数值,所以我们所有非数值数据的处理,需要首先转化编码为数值,然后通过横向连接获取对应的非数值数据。这个过程也就是对非数值数据进行数值编码,然后再通过数值横向连接对它进行解码。 这是数据工厂处理非数值数据的核心思想!(针对目前功能而言2019.8.26)     模型搭建具体思路 1、分析数据的抽取   2、创建数字匹配符,进行与日期表的连接   3、连接日期表,获取日期的时间戳。(日期表是我们数据工厂关于日期的数据分析中频繁使用的基础表) 4、获取日期表的今日值(处理动态日期的关键所在) 5、增加一个连接后的节点(同一表来源的横向连接不能接连来2次) 6、通过我们前面设置的连接符,连接今天的动态值   7、计算日期差 8、分离R分析所涉及的数据,并进行最小日期差计算 9、抽取F跟M分析相关数据,并进行F跟M值的处理。 10、汇总整合R和FM得到的数据 11、根据自己设定的分类划分标准,获取F和M的高低(可以定为低为0、高为1) 12、根据我们编码的RFM分类表去和RFM的取值进行匹配,以获得RFM不同值组合的匹配分类 至此,我们的RFM分析模型就搭建完毕了。通过这个RFM分析,我们可以非常清晰的了解到我们的会员、顾客的购买行为分类。并针对不同分类,采用针对性的促销、激活、发展、提升等等方案。让你的顾客更加活跃、更加粘性、更加有价值!   最终效果就不展示给大家看了,因为我的在这基础上做了改变。下一篇文章给大家分享是我如何利用RFM这个模型来进行销售管理分类分析的。   一切皆是信息,万物源自比特!数字化必定会深刻革命我们的办公和生活!简道云,中小企业数字化之路的绝佳伴侣!             (本文转自简道云用户:龙小马) 编辑于 2021-9-15 10:37 编辑于 2021-9-15 11:01
pandas文档翻译——10分钟介绍pandas
译者语:这是pandas用户手册的第一部分,在所谓的10分钟里(因为10分钟根本看不完)重点介绍了pandas的强大能力。 这是一个面向初学者的简短介绍,你可以在cookbook中查看更多复杂的技巧操作。 源自简道云用户龙小马先生 import numpy as np import pandas as pd pandas对象创建 具体数据结构可以参考数据结构介绍部分。 通过传递一个数值列表我们创建一个series,它会自动创建一个整型索引: s = pd.Series() s 我们传递一个numpy数组来创建一个DataFrame,并给它一个日期型索引和标签列: dates = pd.date_range("20130101", periods=6) dates df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list("ABCD")) df 我们传递一个字典来创建一个DataFrame df2 = pd.DataFrame( { 'A':1.0, 'B':pd.Timestamp('20210101'), 'C':pd.Series(1,index=range(4),dtype='float32'), 'D':np.array(*4,dtype='int32'), 'E':pd.Categorical(), 'F':'foo' } ) df2 这个DataFrame的列具有不同的数据类型 如果你在使用IPython,那么我们可以使用tab来进行列名或者方法名的自动补全。(当然如果我们使用jupyter notebook或者其他python编辑器,那么一般都是有代码自动补全功能的。我用的是jupyter notebook) 查看数据 详情查看基础知识部分 我们可以通过下面的方法来查看最前或最后的数据: 展示索引和列名:可以使用describe()方法来展示DataFrame的快速统计摘要,其中包括行计数、平均值、标准差:可以这样来对数据进行转置可以对列名称进行排序可以对列中的值进行排序 选择数据 我们推荐使用.loc、iloc、at、iat方法来选择数据 直接获取数据 我们可以通过以下方法选择单列,产生一个series,它等同于df.A 可以使用来对行进行切片 df # 第0行到第2行,从第0行开始,不包含第3行。 通过标签值选择数据 通过标签值获取一行的值 df.loc] 通过标签值来获取多轴的值 df.loc] 通过标签切片来截取数据 df.loc 获取一个标量值 df.loc 快速访问标量值 通过位置来获取数据 通过传递整数位置参数来获取数据 通过整数切片来获取数据 通过整数位置参数的列表来获取数据 对行进行切片 对列进行切片 获取标量值 快速获取标量值 逻辑索引(数据过滤) 通过单列的值来过滤数据 通过整个数据集进行条件过滤 通过.isin方法来过滤数据 df2 = df.locdf2 = df2df2.isin()] 设置值 设置一个新列,它会自动根据索引值进行对齐 s1 = pd.Series(list(range(1,7)),index=pd.date_range('2013-01-02',periods=6))s1df = s1df 通过标签名称、标签位置、分配一个array数组来设置值 df.at,'A'] = 0 df.iat = 0 df.loc = np.array( * len(df)) 通过条件过滤来设置值 df2 = df.loc df2 = -df2 缺失值处理 在pandas中主要是使用np.nan来作为缺失值,缺失值默认不参与计算。 reindex方法可以帮我们来重建、增加、删除特定轴的索引。下面我们创建一个数据的副本 df1 = df.reindex(index=dates,columns=list(df.columns) + ) df1.loc = 1 df1 删除任意包含空值的行 df1.dropna(how='any') # axis 默认值为0,即表示行 df1.dropna(axis=1,how='any') # axis = 1 表示删除列 填充缺失值 判断是否是缺失值 df1.isna() 数据操作 统计计算 统计操作一般会过滤掉缺失值 描述性统计计算 df.mean() # 计算各列的平均值 df.mean(1) # 计算各列的平均值 可以使用shift()函数在特定轴上对数据进行移动。sub函数相当于减法df-s,通过axis的设置在选择在index还是column上进行减法操作,它会让每个值就与后面的数据集进行减法。 s = pd.Series(,index=dates).shift(2) s Apply函数 df.apply(np.cumsum) # 计算每列的移动累计值 计算每列最大值与最小值之差 字符串处理方法 series在str方法中打包了一系列的字符串处理方法,它可以操控数组中的每一个字符串元素。 例如,我们可以用str.lower()将字符的大写转换为小写 数据合并 concat 合并 pandas提供了多种多样的方法可以简单便捷地完成series、DataFrame的合并、连接操作。 使用concat()方法合并两个DataFrame merge 连接 这是一种类似SQL中的join的方法 可以做如下笛卡尔积的连接 还可以进行如下左连接 groupby 分组 Group by分组包含以下的操作: Splitting 根据条件对数据分割成组 Applying 分别给不同组应用不同函数 Combining 将结果组合成DataFrame 将数据按A列进行分组,并应用sum()函数操作 对多列进行分组,形成一个多层索引形式的数据格式,同样地,我们还是可以使用sum()函数 数据变形 stack 堆栈 我们创建一个多层索引的DataFrame,然后利用stack()方法,可以把多重索引的列转到行上,完成索引的列转行。 tupless = list( zip(*,]) ) index = pd.MultiIndex.from_tuples(tupless,names=) df = pd.DataFrame(np.random.randn(8,2),index=index,columns=) df2 = df.iloc df2 df2.stack() stack()方法对应的逆操作是unstack(),它可以完成行转列的操作,将行索引转到列上。 df2.stack().unstack() df2.stack().unstack(1) df2.stack().unstack(0) 透视表 我们可以非常简单的使用pivot()方法来为DataFrame生成一个透视表 df = pd.DataFrame( .....: { .....: "A": * 3, .....: "B": * 4, .....: "C": * 2, .....: "D": np.random.randn(12), .....: "E": np.random.randn(12), .....: } .....: ) df df.pivot(index=,columns='C',values=) 时间序列 Pandas具有非常简单、高效、强大的时间序列处理能力,可以在频次转换时执行重新抽样操作(例如,将秒级数据转换成5分钟频次的数据集)。这种操作在金融系统中非常常见,但pandas的能力远不止于此操作。 rng = pd.date_range('2012-01-01',periods=10,freq='S') ts = pd.Series(np.random.randint(0,500,len(rng)),index=rng) ts.resample('5min').sum() 时区处理 rng = pd.date_range('2012-03-06 00:00',periods=5,freq='M') ts = pd.Series(np.random.randn(len(rng)),index=rng) ts.tz_localize('UTC') # 将日期时间转换为带时区的格式 ts.tz_localize('UTC').tz_convert('US/Eastern') # 将本地时区转换为US/Estern时区 转换时间类型 rng = pd.date_range('1/1/2012',periods=5,freq='M') ts = pd.Series(np.random.randn(len(rng)),index=rng) ts.to_period() ts.to_period().to_timestamp() 可视化 matplotlib是Python的一个可视化包,我们默认使用如下语句来导入它 import matplotlib.pyplot as plt plt.close('all') ts = pd.Series(np.random.randn(1000),index=pd.date_range('1/1/2000',periods=1000)) ts = ts.cumsum() ts.plot() 使用plt.plot()方法可以非常方便的为DataFrame所有列绘制条形图 df = pd.DataFrame(np.random.randn(10000,4),index=ts.index,columns=list('ABCD')) # 这里注意上面创建的ts的index,我修改了ts的总量为10000. df = df.cumsum() plt.figure() df.plot() 导入导出数据 在正式文档中,这部分是靠前讲解的,不知在10分钟介绍里,放在了最后的位置 # 处理csv文件 df.to_csv('foo.csv') # 写入csv文件。注意写入的路径 pd.read_csv('foo.csv') # 读取csv文件。如果路径中包含特殊字符,可以使用r'' # 处理HDFS文件 df.to_hdf("foo.h5", "df") # 写入hdfs文件数据 pd.read_hdf("foo.h5", "df") # 读取hdfs文件数据 # 处理Excel文件 df.to_excel('foo.xlsx',sheet_name='Sheet1') # 写入Excel文件 pd.read_excel('foo.xlsx',sheet_name='Sheet1',index_col=None,na_values=)
pandas一行代码转换Excel为字典列表
简道云的群里有人在讨论,如何将excel中的数据处理成简道云子表单的数据类型。Excel的数据大家都熟悉,简道云(帆软2015年推出的无代码应用开发平台)子表单的数据类型为列表中嵌套字典的格式,如下所示 { "data": [ {"a":"a1","b":"b1","c":"c1"}, {"a":"a2","b":"b2","c":"c2"}, {"a":"a3","b":"b3","c":"c3"}, {"a":"a4","b":"b4","c":"c4"} ] } 提问者就是希望能将excel中的数据处理成上面代码中列表中的格式。   方案1   方案1的代码是提问者从网上百度的,具体如下 import pandas as pd import time t0 = time.time # 获取起始时间戳 # 读取文件数据 df = pd.read_excel('excel.xlsx') print(df) head_list = list(df.columns) # 获取数据的列名称 list_dic = # 创建一个空列表 for i in df.values: a_line = dict(zip(head_list,i)) # 将每行数据和列名称转换成字典 list_dic.append(a_line) # 将字典追加到列表上 print(list_dic) print(time.time-t0) 我测试了一个数据大小为(15546行, 26列)的Excel,执行效率如下   方案2   看到上面的代码我想到了作为Python处理数据的翘楚,pandas既然能读取列表嵌套字典型数据那么就可以输出列表嵌套字典型数据。于是搜索之,发现了下面这个方法。 # 读取文件数据 df = pd.read_excel(path) # 将DataFrame转换成列表字典 df.to_dict('records') # record是将每行记录转换成字典 它的执行效率如下图所示,所耗时间仅为方案1的1/10不到。而且数据处理代码只有一行,相比上面的for循环遍历简直是降维秒杀。 下面是数据处理后的样式 [ {'EFFECT_TIME': '2019-05-17 00:00:01','VALID_TIME': '2019-05-17 00:00:01','ORDERGID': '2DD748F7-37E9-4918-B716-77EA6BFF6197'}, {'EFFECT_TIME': '2019-06-16 00:00:01','VALID_TIME': '2019-06-16 00:00:01','ORDERGID': 'A4D3736F-E961-4CAD-BE2D-54D548ECCCF8'}, {'EFFECT_TIME': '2019-06-16 00:00:01','VALID_TIME': '2019-06-16 00:00:01','ORDERGID': 'C5DAB2E5-51E5-4A17-82DB-0EEF4695406A'} ]   to_dict()方法   DataFrame.to_dict(orient='dict',into=<class 'dict'>) 作用:将DataFrame转换成字典 字典类型可以通过下面的参数来控制 orient:str {'dict','list', 'series','split', 'records','index'} 'dict':默认值。如下,它将每列的值转换成了一个字典,值为字典  {列名:{索引:值 , 索引:值 } , 列名:{索引:值 , 索引:值 }} { 'EFFECT_TIME': {0: '2019-05-17 00:00:01',1: '2019-06-16 00:00:01',2: '2019-06-16 00:00:01'}, 'VALID_TIME': {0: '2019-05-17 00:00:01' ,1: '2019-06-16 00:00:01',2: '2019-06-16 00:00:01'}, 'ORDERGID': {0: '2DD748F7-37E9-4918-B716-77EA6BFF6197',1: 'A4D3736F-E961-4CAD-BE2D-54D548ECCCF8',2: 'C5DAB2E5-51E5-4A17-82DB-0EEF4695406A'}, 'CFORMCODE': {0: 'D201900068848', 1: 'D201900138112', 2: 'D201900135280'} } 'list':如下,它将每列的值转换成了一个字典,值为列表  {列名:  , 列名:  } { 'EFFECT_TIME': , 'VALID_TIME': , 'ORDERGID': , 'CFORMCODE': } 'series':如下, { 'EFFECT_TIME': 0 2019 - 05 - 17 00: 00: 01 1 2019 - 06 - 16 00: 00: 01 2 2019 - 06 - 16 00: 00: 01 Name: EFFECT_TIME, dtype: object, 'VALID_TIME': 0 2019 - 05 - 17 00: 00: 01 1 2019 - 06 - 16 00: 00: 01 2 2019 - 06 - 16 00: 00: 01 Name: VALID_TIME, dtype: object, 'ORDERGID': 0 2 DD748F7 - 37E9 - 4918 - B716 - 77E A6BFF6197 1 A4D3736F - E961 - 4 CAD - BE2D - 54 D548ECCCF8 2 C5DAB2E5 - 51E5 - 4 A17 - 82 DB - 0E EF4695406A Name: ORDERGID, dtype: object, 'CFORMCODE': 0 D201900068848 1 D201900138112 2 D201900135280 Name: CFORMCODE, dtype: object } 'split':如下 {index:,columns:,data:} { 'index': , 'columns': , 'data': [ , , ] } 'records':如下,它将DataFrame转换成了一个列表,列表中是每行数据的字典 [ { 'EFFECT_TIME': '2019-05-17 00:00:01', 'VALID_TIME': '2019-05-17 00:00:01', 'ORDERGID': '2DD748F7-37E9-4918-B716-77EA6BFF6197', 'CFORMCODE': 'D201900068848' }, { 'EFFECT_TIME': '2019-06-16 00:00:01', 'VALID_TIME': '2019-06-16 00:00:01', 'ORDERGID': 'A4D3736F-E961-4CAD-BE2D-54D548ECCCF8', 'CFORMCODE': 'D201900138112' }, { 'EFFECT_TIME': '2019-06-16 00:00:01', 'VALID_TIME': '2019-06-16 00:00:01', 'ORDERGID': 'C5DAB2E5-51E5-4A17-82DB-0EEF4695406A', 'CFORMCODE': 'D201900135280' } ] 'index':如下,它将DataFrame转换成 {0:{列1:值,列2:值},1:{列1:值,列2:值},2:{列1:值,列2:值}} { 0: { 'EFFECT_TIME': '2019-05-17 00:00:01', 'VALID_TIME': '2019-05-17 00:00:01', 'ORDERGID': '2DD748F7-37E9-4918-B716-77EA6BFF6197', 'CFORMCODE': 'D201900068848' }, 1: { 'EFFECT_TIME': '2019-06-16 00:00:01', 'VALID_TIME': '2019-06-16 00:00:01', 'ORDERGID': 'A4D3736F-E961-4CAD-BE2D-54D548ECCCF8', 'CFORMCODE': 'D201900138112' }, 2: { 'EFFECT_TIME': '2019-06-16 00:00:01', 'VALID_TIME': '2019-06-16 00:00:01', 'ORDERGID': 'C5DAB2E5-51E5-4A17-82DB-0EEF4695406A', 'CFORMCODE': 'D201900135280' } } to_dict()与to_json()有异曲同工之妙,而且这俩函数的参数值以及所得结果也很类似,不过to_json()的返回值为json字符串。 有兴趣的可以看看 https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_json.html 这个案例让我再次感受到pandas处理数据的简洁和高效 人生苦短,我用python! 编辑于 2021-8-31 13:52 编辑于 2021-8-31 13:52
Python+datax 自动批量执行datax任务完成离线数据同步
异构数据库离线数据同步工具翘楚——Datax 在之前的文章中我们介绍过阿里的开源离线数据同步工具——datax,我们可以使用datax来完成我们异构数据库之间的离线数据同步工作,它可以通过给予的主键(文本或数值)进行任务切分来同步进行,数据同步的效率还是非常高效的。 下图是datax钉钉交流群网友的任务截图。 阿里ETL工具——DataX使用简介 阿里开源ETL——DataX与Kettle联用 https://github.com/alibaba/DataX  (这是阿里的github地址) 在日常工作中经常会用到datax来进行数据同步,但是每次都需要手动来配置json任务显得非常繁琐,作为一个热爱偷懒事业的人,是不允许继续这样下去的! 于是想到用python来编写个小脚本来驱动datax任务的执行。我呢,就看着它干活就好了! python脚本驱动datax 首先,我们需要归纳下自己经常进行数据同步的数据库类型,我这边经常用到oracle、mysql、sqlserver这传统关系型数据库哥仨。因此先准备几个样例json作为我们Python调用的模板。 然后我们把需要用到的数据库连接整理到一个数据库连接的类中,然后通过import导入 import os # 用来执行python调用命令 import time # 获取任务执行时间 import pandas as pd # 处理json import threading # 多线程执行任务 from db_conn import Db_conn as db # 从自己编写的数据库连接模块导入数据库连接 任务的启动需要我们首先确定几个变量, 运行平台(windows/linux) reader类型 writer类型 reader数据库信息 writer数据库信息 要进行同步的表对应关系 # 任务执行平台选择 plat_form = 'windows' # 数据库可选列表 reader = 'sqlserver' # 读取数据的数据库类型 writer = 'oracle' # 写入数据的数据库类型 # 不同的数据库名称对应不同的连接函数调用。在 reader_db = '' # 读取数据的业务系统数据库名称 writer_db = '' # 写入数据的业务系统数据库名称 # 需要同步的表名称对应关系。我这里用的是字典列表来处理 tables = [ {'reader_table':'','writer_table':'','splitPk':''}, {'reader_table':'','writer_table':'','splitPk':''}, {'reader_table':'','writer_table':'','splitPk':''}, ] 我这里处理的思路是统一处理同一个reader和writer的批量任务,也可以修改成不同reader和writer的批量任务) 接下来,我们开始遍历这个字典列表,获取需要同步的表的对照关系和切分主键字段 for i in range(len(tables)): reader_table = tables writer_table = tables splitPk = tables 下面,我们首先获取下json模板信息,因为我们把json都放在了这个python脚本同目录下面,因此我们使用os来获取这个脚本文件的所属文件夹绝对路径 current_path = os.path.dirname(os.path.abspath(__file__)) 根据前面提供的平台参数和reader、writer参数,我们获取需要调用的json文件 if plat_form == 'windows': json_file = current_path + '\\' + reader.lower().title() + '2' + writer.lower().title() + '.json' # windows执行 else: json_file = current_path + '/' + reader.lower().title() + '2' + writer.lower().title() + '.json' # linux执行 因为路径信息在windows和linux下用了不同的斜杠。 再根据提供的数据库来获取对应的数据库连接 if reader_db == 'a': conn = db.get_ERP_Re1_outer_conn() elif reader_db == 'b': conn = db.get_ERP业务242_2017_outer_conn() elif reader_db == 'c': conn = db.get_ERP业务242_2016_outer_conn() 然后我们就可以读取这个json了 read_df = pd.read_json(json_file) reader_parameter = read_df.to_dict() # 获取需要修改的reader部分 writer_parameter = read_df.to_dict() # 获取需要修改的writer部分 在json文件中,我们需要提供给reader和writer下面这些信息   jdbcUrl、username、password、table、splitpk、column (我们做的全量多任务分割同步,所以querysql和presql参数我们不使用了) 数据库的这些连接信息(jdbcUrl、username、password)我们通过获取数据仓库数据库中某个表中存储的数据库连接信息,如下图所示 def get_db_info(plat_form,dbname): """获取数据库的连接信息""" if plat_form == 'windows': BI_conn = db.get_BI20_outer_conn() # windows中我们用外网ip else: BI_conn = db.get_BI20_inner_conn() # linux中我们用内网ip sql = f''' SELECT * FROM ETL_DB_INFO WHERE DB_ALIAS = '{dbname}' ''' db_info = pd.read_sql(sql,BI_conn) return db_info reader_dbinfo = get_db_info(plat_form,reader_db) writer_dbinfo = get_db_info(plat_form,writer_db) 表名称和分割主键是由前面的参数提供 我们只需要获取下对应表的字段信息即可 # 获取要读取数据的表的列信息,以列表形式给出 columns = list(pd.read_sql(f'select * from {reader_table} where 1=0',conn).columns) 拿到这些基本信息之后我们就对json来进行修改赋值 reader_parameter = ] reader_parameter = reader_dbinfo.loc reader_parameter = reader_dbinfo.loc reader_parameter = reader_parameter = columns # 如果没有给出splitpk,那么我们默认获取表的第一个字段作为splitpk if len(splitPk) > 0: reader_parameter = splitPk else: reader_parameter = columns writer_parameter = writer_dbinfo.loc writer_parameter = writer_dbinfo.loc writer_parameter = writer_dbinfo.loc writer_parameter = writer_parameter = columns read_df.to_json(f'{json_file}') # 将json写入模板文件  json修改之后,我们就在系统上执行python调用datax执行这个json """执行datax""" time1 = time.time() if plat_form == 'windows': os.system('chcp 65001') # 在windows上防止执行日志出现乱码 os.system(f'python D:\\datax\\bin\\datax.py {json_file}') # windows本地执行 else: os.system(f'python3 /home/Python/datax/bin/datax.py {json_file}') # linux服务器执行 print(f'表{reader_table}执行完毕!耗时',time.time()-time1,'s') 上面执行命令中的datax.py的路径大家自行定义。 在实际调用时,我利用多线程来同步执行多个表的执行 threading.Thread(target=update_json,args=(plat_form,reader,writer,reader_db,writer_db,reader_table,writer_table,splitPk)).start()   到这里,我们就完成了这个python自动调用datax执行json进行离线数据同步的小脚本了。                                         本文转自简道云用户:龙小马
个人成就
内容被浏览21,961
加入社区2年252天
返回顶部