• Python量化交易


    数据分析项目案例

    第一步,我们先导入tushare:

    # 导入tushareimport tushare as tspro = ts.pro_api()
    沪深港通标的
    很多投资者倾向于投资沪深港通的标的,因为这些股票得到了更多国际投资者的青睐。在tushare中,我们通过stock_basic接口获取股票列表,其中is_hs参数用于筛选沪深港通标的列表,具体规则如下:

    沪股通标的:is_hs="H";
    深股通标的:is_hs="S";
    其他:is_hs="N".
    # 沪股通股票列表pro.stock_basic(is_hs='H').head()

    # 深股通股票列表pro.stock_basic(is_hs='S').head()

    # 非沪深港通股票列表pro.stock_basic(is_hs='N').head()

    上市状态
    在stock_basic接口中,我们可以用list_status参数筛选不同上市状态的股票。

    上市状态:list_status="L";
    退市状态:list_status="D";
    暂停上市状态:list_status="P".
    # 正常上市股票pro.stock_basic(list_status='L').head()

    # 已退市股票pro.stock_basic(list_status='D').head()

    交易所
    我们还可以看分别在上交所和深交所上市的股票列表,只需要在stock_basic中传入exchange参数即可。

    上交所:exchange="SSE";
    深交所:exchange="SZSE:.
    # 上交所股票pro.stock_basic(exchange='SSE').head()

    行业
    除了参数中提供的筛选维度,我们还可以获取所有股票列表数据之后,用一些字段进行筛选。比如说行业:

    df = pro.stock_basic()

    df.query('industry == "银行"').head()

    上市板块
    我们还可以按照上市板块来挑选股票,这一点也很有用,有些投资人侧重于某个板块的股票,比如中小板、创业板等。

    df = pro.stock_basic()

    df.query('market == "创业板"').head()

    地区
    我们还能挑选属于某个特定地区的股票。当我们需要寻找地域联动效应或者某个地区爆出了某个利好时,这个筛选方法会很有帮助。

    df = pro.stock_basic()df.query('area == "深圳"').head()

    上市公司基本信息
    在获取了股票列表之后,我们可能还想要了解一下它们的基本信息,比如注册资本、所在城市、经营范围等,这时我们可以使用stock_company接口。

    接口默认仅提供了部分字段,需要更多字段的可以用fields参数来指定所需要的列。

    pro.stock_company().head(1).T

    获取深圳本地股票

    我们来看一个案例,比如说之前有国家帮助中小企业解决质押风险,深圳国资委率先响应,然后我们想看一下可能受益的股票有哪些,因此我们想要先找到深圳的本地股列表,并且查看他们的主营业务、员工人数。

    # 获取深圳本地上市公司股票列表import pandas as pd# 获取上市公司信息fields = ('ts_code,exchange,chairman,province,' 'city,office,employees,main_business')df = pro.stock_company(fields=fields)df.query('city == "深圳市"').head()

    获取员工数超过十万的上市公司股票
    可能我们还想通过员工数来筛选出大型的企业,这时我们可以通过employees字段完成筛选。

    df = pro.stock_company()df.query('employees >= 100000')

    是不是很简单?不过tushare的强大远不止于此
    ————————————————

    分享一下获取股票基本信息的内容,主要包括以下三个知识点,希望对您能有所帮助:

    (1)从Tushare获取数据
    (2)写入Mysql
    (3)导入Excel
    后续,我会加入一些复杂的功能,比如定时更新、logging日志等等。

    1. """
    2. 接口:stock_basic
    3. 描述:获取基础信息数据,包括股票代码、名称、上市日期、退市日期等
    4. 更新频率:one week or long
    5. """
    6. import tushare as ts
    7. import pymysql
    8. import pandas as pd
    9. # 连接数据库,传参数的,返回df
    10. def get_mysql_data(sql):
    11. db = pymysql.connect(host="localhost",
    12. user="root",
    13. password="root",
    14. db="STOCK",
    15. charset='utf8')
    16. cur = db.cursor()
    17. cur.execute(sql)
    18. data = cur.fetchall()
    19. columnDes = cur.description # 获取连接对象的描述信息
    20. columnNames = [columnDes[i][0] for i in range(len(columnDes))]
    21. df = pd.DataFrame([list(i) for i in data], columns=columnNames)
    22. cur.close()
    23. db.commit()
    24. db.close()
    25. return df
    26. # 将已完成的数据表,导出到excel中
    27. def to_excel():
    28. sql = "select * from stock_basic"
    29. df = get_mysql_data(sql)
    30. df.to_excel(r'D:\0.STOCK\Excel_File\stock_basic.xlsx',index=False)
    31. print('<=== !!!导入成功!!! =====>')
    32. # 返回相应接口的数据
    33. def get_data():
    34. # 只需要在第一次或者token失效后调用
    35. ts.set_token('your token')
    36. pro = ts.pro_api()
    37. # 查询当前所有正常上市交易的股票列表
    38. data = pro.stock_basic(exchange='', list_status='L',
    39. fields='ts_code,symbol,name,area,industry,market,exchange,list_status,list_date,is_hs')
    40. return data
    41. # 连接数据库,清洗掉原表,并重新写入数据
    42. def write_data():
    43. db = pymysql.connect(host="localhost",
    44. user="root",
    45. password="123",
    46. db="STOCK",
    47. charset='utf8')
    48. cur = db.cursor()
    49. cur.execute("truncate TABLE stock_basic")
    50. para = []
    51. data = get_data() # 获取接口的数据
    52. print('<=== !!!获取成功!!! =====> 共有', data.shape[0], '个股票数据')
    53. print(data.head())
    54. for i in range(0, len(data)):
    55. para.append((i+1, data.loc[i, 'ts_code'], data.loc[i, 'symbol'], data.loc[i, 'name'], data.loc[i, 'area'],
    56. data.loc[i, 'industry'], data.loc[i, 'market'], data.loc[i, 'exchange'],
    57. data.loc[i, 'list_status'],
    58. data.loc[i, 'list_date'], data.loc[i, 'is_hs']))
    59. sql = """
    60. insert into stock_basic(id,ts_code,symbol,name,area,industry,market,exchange,list_status,list_date,is_hs) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
    61. """
    62. cur.executemany(sql, para)
    63. # 查询写入的条数
    64. sql_query = "SELECT ts_code from stock_basic"
    65. cur.execute(sql_query)
    66. sql_data = cur.fetchall()
    67. sql_num = len(sql_data)
    68. print('Mysql数据库写入成功,共写入', sql_num, '个股票数据')
    69. cur.close()
    70. db.commit()
    71. db.close()
    72. if __name__ == '__main__':
    73. write_data() # 清除到原表,重新写入
    74. to_excel() # 导出到表格中

    1、股票分析

    需求:

    使用tushare包获取某股票的历史行情数据。

    输出该股票所有收盘比开盘上涨3%以上的日期。

    输出该股票所有开盘比前日收盘跌幅超过2%的日期。

    # 需求四:假如我从2010年1月1日开始,每月第一个交易日买入1手股票,每年最后一个交易日卖出所有股票,到今天为止,我的收益如何?

    需求一:使用tushare包获取某股票的历史行情数据。

    #获取行情

    df = ts.get_k_data(code="600519",start='2000-01-01')#保存到本地

    df.to_csv('./maotai.csv')#读取本地csv文件数据

    df = pd.read_csv('./maotai.csv')#删除 Unnamed: 0 这一列,将 date 列转为时间类型,并设置为 index 列

    df.drop(labels='Unnamed: 0',axis=1,inplace=True)

    df['date'] = pd.to_datetime(df['date'])

    df.set_index('date',inplace=True)print(df.info()) #查看整个数据集合中各个数据类型

    print(df)

    需求二:输出该股票所有收盘比开盘上涨3%以上的日期。

    #(收盘-开盘)/开盘 > 0.03 返回值为 boolean 值,将 boolean 作为行索引来使用

    #在分析的过程中如果产生了boolean值则下一步马上将布尔值作为源数据的行索引#如果布尔值作为df的行索引,则可以取出true对应的行数据,忽略false对应的行数据#print((df['close'] - df['open'])/df['open'] > 0.03) # 获取了True对应的行数据(满足需求的行数据)

    print(df.loc[(df['close'] - df['open']) / df['open'] > 0.03].index)

    需求三:输出该股票所有开盘比前日收盘跌幅超过2%的日期。

    #(今日开盘价-昨日收盘价)/昨日收盘价 < -0.02#print(df['close'].shift(1)) # 使 df['close'] 列整体下移一位

    print(df.loc[(df['open'] - df['close'].shift(1)) / df['close'].shift(1) < -0.02].index)

    # 需求四:假如我从2010年1月1日开始,每月第一个交易日买入1手股票,每年最后一个交易日卖出所有股票,到今天为止,我的收益如何?

    - 分析:

    - 时间节点:2010-2020

    - 一手股票:100支股票

    - 买:

    - 一个完整的年需要买入1200支股票

    - 卖:

    - 一个完整的年需要卖出1200支股票

    -买卖股票的单价:

    - 开盘价

    #买股票:找每个月的第一个交易日对应的行数据(捕获到开盘价)==》每月的第一行数据#根据月份从原始数据中提取指定的数据#每月第一个交易日对应的行数据

    new_df = df['2010-01-01':]

    mairu= new_df.resample('M').first()['open'].sum() * 100 #数据的重新取样,取出每月的第一支股票

    maichu = new_df.resample('A').last()['open'][:-1].sum() * 1200 #取出每年最后一个交易日的收盘价

    yu = new_df['close'][-1] * 600 #剩余股票价值

    #print(new_df.resample('M').first()['open']*100)#print(new_df.resample('A').last()['close'][:-1] * 100)

    print(maichu - mairu + yu)

    双均线策略

    需求一:计算该股票历史数据的5日均线和60日均线

    - 什么是均线?

    - 对于每一个交易日,都可以计算出前N天的移动平均值,然后把这些移动平均值连起来,成为一条线,就叫做N日移动平均线。移动平均线常用线有5天、10天、30天、60天、120天和240天的指标。

    - 5天和10天的是短线操作的参照指标,称做日均线指标;

    - 30天和60天的是中期均线指标,称做季均线指标;

    - 120天和240天的是长期均线指标,称做年均线指标。

    - 均线计算方法:MA=(C1+C2+C3+...+Cn)/N C:某日收盘价 N:移动平均周期(天数)

    df = ts.get_k_data(code="600519", start='2000-01-01')

    df.to_csv('./maotai.csv')

    df= pd.read_csv('./maotai.csv')

    df.drop(labels='Unnamed: 0',axis=1,inplace=True)

    df['date'] = pd.to_datetime(df['date'])

    df.set_index('date',inplace=True)

    ma5= df['close'].rolling(5).mean() #5日均线

    ma30 = df['close'].rolling(30).mean() #30日均线

    plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签

    plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号

    plt.plot(ma5[20:80],'h-r', label='ma5')

    plt.plot(ma30[20:80],'h-b', label='ma30')

    plt.legend()

    plt.show()

    需求二:

    - 分析输出所有金叉日期和死叉日期

    - 股票分析技术中的金叉和死叉,可以简单解释为:

    - 分析指标中的两根线,一根为短时间内的指标线,另一根为较长时间的指标线。

    - 如果短时间的指标线方向拐头向上,并且穿过了较长时间的指标线,这种状态叫“金叉”

    - 如果短时间的指标线方向拐头向下,并且穿过了较长时间的指标线,这种状态叫“死叉”

    - 一般情况下,出现金叉后,操作趋向买入;死叉则趋向卖出。当然,金叉和死叉只是分析指标之一,要和其他很多指标配合使用,才能增加操作的准确性。

    #分析输出所有金叉日期和死叉日期

    df = pd.read_csv('./maotai.csv')

    df.drop(labels='Unnamed: 0', axis=1, inplace=True)

    df['date'] = pd.to_datetime(df['date'])

    df.set_index('date', inplace=True)

    ma5= df['close'].rolling(5).mean()

    ma30= df['close'].rolling(30).mean()

    s5= ma5[30:] < ma30[30:]

    s30= ma5[30:] > ma30[30:]

    df= df[30:]

    down= s5 & s30.shift(1)print(df.loc[down].index) #死叉

    up= ~(s5 | s30.shift(1))print(df.loc[up].index) #金叉

    需求三:如果我从假如我从2010年1月1日开始,初始资金为100000元,金叉尽量买入,死叉全部卖出,则到今天为止,我的炒股收益率如何?

    df = pd.read_csv('./maotai.csv')

    df.drop(labels='Unnamed: 0', axis=1, inplace=True)

    df['date'] = pd.to_datetime(df['date'])

    df.set_index('date', inplace=True)

    ma5= df['close'].rolling(5).mean()

    ma30= df['close'].rolling(30).mean()

    s5= ma5[30:] < ma30[30:]

    s30= ma5[30:] > ma30[30:]

    df= df[30:]

    up= ~(s5 | s30.shift(1)) #金叉

    down = s5 & s30.shift(1) #死叉

    up_code= Series(data=1, index=(df.loc[up].index))

    down_code= Series(data=0, index=(df.loc[down].index))

    s=up_code.append(down_code)

    s= s.sort_index()['2010-01-01']

    first_monry= 100000 #本金,不变

    money = first_monry #可变的,买股票话的钱和卖股票收入的钱都从该变量中进行操作

    hold = 0 #持有股票的数量(股数:100股=1手)

    for i in range(0, len(s)): #i表示的s这个Series中的隐式索引

    #i = 0(死叉:卖) = 1(金叉:买)

    if s[i] == 1: #金叉的时间

    #基于100000的本金尽可能多的去买入股票

    #获取股票的单价(金叉时间对应的行数据中的开盘价)

    time = s.index[i] #金叉的时间

    p = df.loc[time]['open'] #股票的单价

    hand_count = money // (p * 100) #使用100000最多买入多少手股票

    hold = hand_count * 100money-= (hold * p) #将买股票话的钱从money中减去

    else:#将买入的股票卖出去

    #找出卖出股票的单价

    death_time =s.index[i]

    p_death= df.loc[death_time]['open'] #卖股票的单价

    money += (p_death * hold) #卖出的股票收入加入到money

    hold =0#如何判定最后一天为金叉还是死叉

    last_monry = hold * df['close'][-1] #剩余股票的价值

    #总收益

    money + last_monry -first_monryprint(money)

    人口分析项目

    -需求:-导入文件,查看原始数据-将人口数据和各州简称数据进行合并-将合并的数据中重复的abbreviation列进行删除-查看存在缺失数据的列- 找到有哪些state/region使得state的值为NaN,进行去重操作- 为找到的这些state/region的state项补上正确的值,从而去除掉state这一列的所有NaN-合并各州面积数据areas-我们会发现area(sq.mi)这一列有缺失数据,找出是哪些行-去除含有缺失数据的行-找出2010年的全民人口数据-计算各州的人口密度- 排序,并找出人口密度最高的州

    #导入文件,查看原始数据

    abb = pd.read_csv(r'H:\py\课件\2-课件\2_数据分析\课件\data\state-abbrevs.csv') #state(州的全称)abbreviation(州的简称)

    area = pd.read_csv(r'H:\py\课件\2-课件\2_数据分析\课件\data\state-areas.csv') #state州的全称,area (sq. mi)州的面积

    pop = pd.read_csv(r'H:\py\课件\2-课件\2_数据分析\课件\data\state-population.csv')#state/region简称,ages年龄,year时间,population人口数量

    #将人口数据和各州简称数据进行合并

    abb_pop = pd.merge(abb,pop,left_on='abbreviation',right_on='state/region')

    abb_pop#将合并的数据中重复的abbreviation列进行删除

    abb_pop2.drop(labels='abbreviation',axis=1,inplace=True)

    abb_pop2#查看存在缺失数据的列

    abb_pop2.isnull().any(axis=0)#找到有哪些state/region使得state的值为NaN,进行去重操作

    abb_pop.loc[abb_pop['state'].isnull()]['state/region'].unique()#为找到的这些state/region的state项补上正确的值,从而去除掉state这一列的所有NaN#合并各州面积数据areas#我们会发现area(sq.mi)这一列有缺失数据,找出是哪些行#去除含有缺失数据的行#找出2010年的全民人口数据#计算各州的人口密度#排序,并找出人口密度最高的州

    消费记录分析

    第一部分

    第一部分:数据类型处理-数据加载-字段含义:-user_id:用户ID-order_dt:购买日期-order_product:购买产品的数量-order_amount:购买金额-观察数据-查看数据的数据类型-数据中是否存储在缺失值-将order_dt转换成时间类型-查看数据的统计描述-计算所有用户购买商品的平均数量-计算所有用户购买商品的平均花费- 在源数据中添加一列表示月份:astype('datetime64[M]')

    代码实现

    importpandas as pdfrom pandas importDataFrame#数据加载

    df = pd.read_csv(r'H:\py\高级\数据分析\科学计算基础包-numpy\CDNOW_master.txt',header=None,sep='\s+',names=['user_id','order_dt','order_product','order_amount'])

    df#查看数据的数据类型

    df.info()#数据中是否存储在缺失值#df.isnull().any()

    df.notnull().all()#将 order_amount 转换成时间类型

    df['order_dt'] = pd.to_datetime(df['order_dt'],format='%Y%m%d')

    df#查看数据的统计描述

    df.describe()#在源数据中添加一列表示月份:astype('datetime64[M]')

    df['month'] = df['order_dt'].astype('datetime64[M]')

    df

    View Code

    第二部分

    第二部分:按月数据分析-用户每月花费的总金额-绘制曲线图展示-所有用户每月的产品购买量-所有用户每月的消费总次数- 统计每月的消费人数

    代码实现

    #用户每月花费的总金额

    df.groupby(by='month')['order_amount'].sum()#绘制曲线图展示

    importmatplotlib.pyplot as plt

    plt.plot(df.groupby(by='month')['order_amount'].sum())

    df.groupby(by='month')['order_amount'].sum().plot()#所有用户每月的产品购买量

    df.groupby(by='month')['order_product'].sum()#所有用户每月的消费总次数

    df.groupby(by='month')['user_id'].count()#统计每月的消费人数

    df.groupby(by='month')['user_id'].nunique()

    View Code

    第三部分

    第三部分:用户个体消费数据分析-用户消费总金额和消费总次数的统计描述-用户消费金额和消费产品数量的散点图-各个用户消费总金额的直方分布图(消费金额在1000之内的分布)- 各个用户消费的总数量的直方分布图(消费商品的数量在100次之内的分布)

    代码实现

    #用户消费总金额和消费总次数的统计描述

    df.groupby('user_id')['order_amount'].sum()

    df.groupby('user_id')['order_product'].count()#用户消费金额和消费产品数量的散点图

    order_amount = df.groupby('user_id')['order_amount'].sum()

    order_product= df.groupby('user_id')['order_product'].sum()

    plt.scatter(order_amount,order_product)#各个用户消费总金额的直方分布图(消费金额在1000之内的分布)

    df.groupby(by='user_id').sum().query('order_amount <= 1000')['order_amount'].hist()#各个用户消费的总数量的直方分布图(消费商品的数量在100次之内的分布)

    df.groupby(by='user_id').sum().query('order_product <= 100')['order_product'].hist()

    View Code

    第四部分

    第四部分:用户消费行为分析-用户第一次消费的月份分布,和人数统计-绘制线形图-用户最后一次消费的时间分布,和人数统计-绘制线形图-新老客户的占比-消费一次为新用户-消费多次为老用户-分析出每一个用户的第一个消费和最后一次消费的时间- agg(['func1','func2']):对分组后的结果进行指定聚合-分析出新老客户的消费比例-用户分层-分析得出每个用户的总购买量和总消费金额and最近一次消费的时间的表格rfm-RFM模型设计-R表示客户最近一次交易时间的间隔。- /np.timedelta64(1,'D'):去除days-F表示客户购买商品的总数量,F值越大,表示客户交易越频繁,反之则表示客户交易不够活跃。-M表示客户交易的金额。M值越大,表示客户价值越高,反之则表示客户价值越低。-将R,F,M作用到rfm表中-根据价值分层,将用户分为:-重要价值客户-重要保持客户-重要挽留客户-重要发展客户-一般价值客户-一般保持客户-一般挽留客户-一般发展客户- 使用已有的分层模型即可rfm_func

    代码实现

    importpandas as pdfrom pandas importDataFrame#读取数据

    df = pd.read_csv(r'H:\py\高级\数据分析\科学计算基础包-numpy\CDNOW_master.txt',sep='\s+',header=None,names=['user_id','order_dt','order_product','order_amount'])#转为时间格式

    df['order_dt'] = pd.to_datetime(df['order_dt'],format='%Y%m%d')#增加月份一列

    df['month'] = df['order_dt'].astype('datetime64[M]')#用户第一次消费的月份分布,和人数统计,绘制线形图

    df.groupby(by='user_id')['month'].min().value_counts().plot()#用户最后一次消费的时间分布,和人数统计,绘制线形图

    df.groupby(by='user_id')['month'].max().value_counts().plot()#新老客户的占比

    new_old_user = df.groupby(by='user_id')['order_dt'].agg(['min','max'])

    val= (new_old_user['min'] == new_old_user['max']).value_counts()#新用户占比

    val[True]/(val[True] +val[False])#老用户占比

    val[False]/(val[True] + val[False])

    View Code

    构建 RFM 数据表

    #分析得出每个用户的总购买量和总消费金额and最近一次消费的时间的表格rfm

    rfm = df.pivot_table(index='user_id',aggfunc={'order_product':'sum','order_amount':'sum','order_dt':'max'})

    rfm#R表示客户最近一次交易时间的间隔

    importnumpy as np

    new_date= df['order_dt'].max() #数据中最大时间,假设为当前时间

    rfm['R'] = -(rfm.groupby(by='user_id')['order_dt'].max()-new_date)/np.timedelta64(1,'D')

    rfm#F表示客户购买商品的总数量,F值越大,表示客户交易越频繁,反之则表示客户交易不够活跃#M表示客户交易的金额。M值越大,表示客户价值越高,反之则表示客户价值越低#将R,F,M作用到rfm表中

    #删除 order_dt 列

    rfm.drop(labels='order_dt',axis=1,inplace=True)#对列进行重命名

    rfm.columns = ['M','F','R']

    rfm

    View Code

    用户分层

    defrfm_func(x):

    level= x.map(lambda x:'1' if x>=0 else '0')

    val= level.R + level.F +level.M

    dit={'111':'重要价值客户','011':'重要保持客户','101':'重要挽留客户','001':'重要发展客户','110':'一般价值客户','010':'一般保持客户','100':'一般挽留客户','000':'一般发展客户',

    }

    respons=dit[val]returnrespons

    rfm['level'] = rfm.apply(lambda x:x-x.mean()).apply(rfm_func,axis=1)

    rfm

    View Code

    第五部分:用户生命周期

    第五部分:用户的生命周期-将用户划分为活跃用户和其他用户-统计每个用户每个月的消费次数-统计每个用户每个月是否消费,消费为 1 否则为 0-知识点:DataFrame的apply和applymap的区别-applymap:返回df-将函数做用于DataFrame中的所有元素(elements)-apply:返回Series-apply()将一个函数作用于DataFrame中的每个行或者列-将用户按照每一个月份分成:-unreg:观望用户(前两月没买,第三个月才第一次买,则用户前两个月为观望用户)-unactive:首月购买后,后序月份没有购买则在没有购买的月份中该用户的为非活跃用户-new:当前月就进行首次购买的用户在当前月为新用户-active:连续月份购买的用户在这些月中为活跃用户- return:购买之后间隔n月再次购买的第一个月份为该月份的回头客

    代码实现

    importpandas as pdfrom pandas importDataFrame

    df= pd.read_csv(r'H:\py\高级\数据分析\科学计算基础包-numpy\CDNOW_master.txt',sep='\s+',header=None,names=['user_id','order_dt','order_product','order_amount'])

    df['order_dt'] = pd.to_datetime(df['order_dt'],format='%Y%m%d')

    df['month'] = df['order_dt'].astype('datetime64[M]')

    df#统计每个用户每个月的消费次数

    month_sum = df.pivot_table(index='user_id',values='order_dt',aggfunc='count',columns='month').fillna(0)#统计每个用户每个月是否消费,消费为 1 否则为 0

    month_sum = df.pivot_table(index='user_id',values='order_dt',aggfunc='count',columns='month').fillna(0)

    df_purchase= month_sum.applymap(lambda x:1 if x>0 else0 )

    df_purchase

    View Code

    区分用户类别

    #将df_purchase中的原始数据0和1修改为new,unactive......,返回新的df叫做df_purchase_new#固定算法

    month_sum = df.pivot_table(index='user_id',values='order_dt',aggfunc='count',columns='month').fillna(0)

    one_zero= month_sum.applymap(lambda x:'1' if x>0 else '0')defactive_status(data):

    status= []#某个用户每一个月的活跃度

    for i in range(18):#若本月没有消费

    if data[i] ==0:if len(status) >0:if status[i-1] == 'unreg':

    status.append('unreg')else:

    status.append('unactive')else:

    status.append('unreg')#若本月消费

    else:if len(status) ==0:

    status.append('new')else:if status[i-1] == 'unactive':

    status.append('return')elif status[i-1] == 'unreg':

    status.append('new')else:

    status.append('active')returnstatus

    pivoted_status= df_purchase.apply(active_status,axis=1)#转为 list 格式

    pivoted_status_list =pivoted_status.values.tolist()#生成新的数据表#new_start_info = DataFrame(data=start_list)#生成新的数据表并更换回原 index

    new_start_info = DataFrame(data=pivoted_status_list,index=month_sum.index,columns=month_sum.columns)

    new_start_info

    View Code

    - 每月【不同活跃】用户的计数

    - purchase_status_ct = df_purchase_new.apply(lambda x : pd.value_counts(x)).fillna(0)

    - 转置进行最终结果的查看

    new_start_info_ct = new_start_info.apply(lambdax : pd.value_counts(x)).fillna(0)

    new_start_info_ct

    new_start_info_ct.T

  • 相关阅读:
    深度学习中图像格式选用jpg还是png?答:png
    JVM调优经历
    数列计算
    ESP Insights 支持通过高级筛选进行分组分析
    Java项目:JSP小说网
    5.XSS-反射型(post)利用:获取cookie
    解决:git SSL certificate problem: unable to get local issuer certificate
    Ubuntu下载
    GitHub 曝出漏洞,或导致 4000 多个存储库遭受劫持攻击
    向量数据库的分类概况
  • 原文地址:https://blog.csdn.net/qq_22473611/article/details/126311555