自律使我自由

从来都没有完全的自由。

如果不加节制的放纵自己,大吃大喝、熬夜不睡、畅玩游戏,那么就会导致现在的状态,那就是肥胖、精神差、血脂高、颈椎病等等;

放纵,导致了恶果。

而如果想要身体轻盈、健康、精神饱满、激情四射,那就不能通过放纵来实现,而是节制。

如果做到了这些节制:
1. 不吃高糖、高脂、高油腻的食物;
2. 吃饭不吃过度饱;
3. 多次健康食物,比如粗粮、高蛋白;
4. 坐的时间长,就起来活动;
5. 经常做颈椎操,些许的锻炼;
6. 经常散散步走走路,可以尝试快走,做做下蹲和俯卧撑;
7. 少熬夜;
8. 减少趴着睡,伤颈椎,可以用冥想的方式休息;

那么逐步的,我会收获这些健康:
1. 身体的指标回归正常,比如高脂、肥胖;
2. 精神状态变得饱满和有活力;
3. 更加的高产、学习的更加快;

我很向往有一天,自己能身体轻盈、放松自在;

而这,需要节制来实现,而不是放纵;

放纵只能获得当前的满足、过后就是恶果和痛苦;

当前的节制,却能换来将来长期的健康和快乐。

自律使我自由;
当前的自律,带来长期的自由。

文章写的好,但是没人看,原来标题可以这么写

有一种方法,就是三段式标题。

三段式,来自百度百科:

地址:https://baike.baidu.com/item/%E4%B8%89%E6%AE%B5%E5%BC%8F/10868374?fr=aladdin

···
德国哲学家黑格尔用来说明发展过程公式。
认为一切发展都经历三个阶段,
即发展的起点(正题),
对立面的显现(反题),
对立面的统一(合题)。

反题否定正题,合题否定反题,合题是否定之否定。

黑格尔把三段式作为论证其客观唯心主义工具,却为事物从低级到高级发展的辩证法开辟了道路。
···

来自头条起标题的一个说明:

三段式是指用三个小分句组成标题的形式,是最容易出爆款的句式,因为它的套路比较清晰明了易模仿,标题中可以容纳更多的信息点,然后用递进、转折增加标题的争议。大数据显示,三段式的标题比两段式的标题更加吸引用户点击。

例子:

原标题 :这样表达,你的听众才会被打动!
点击/展示 :4338/112326=3.86%

优化 标题 :开会时,怎么发言最有水平?一个小技巧让领导对你刮目相看
点击/展示 :107387/997934=10.76%

案例解析 :原标题太过简略,没有具体场景,优化后的标题设置了“职场”场景,给用户强烈代入感,并且突出了实用价值“让领导对你刮目相看”。

另一个例子

推荐系统实现相似推荐的流程和资源

视频位于:链接

需要的资源整理:

本视频涉及的相关资源:

1、jieba中文分词库:

https://github.com/fxsjy/jieba

2、spark word2vec计算:

http://spark.apache.org/docs/latest/ml-features.html#word2vec

3、腾讯开源800万word2vec数据:

https://ai.tencent.com/ailab/nlp/embedding.html

4、Scipy的相似度计算函数:

https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.spatial.distance.cosine.html

5、相似度近邻搜索优化算法LSH局部敏感哈希

http://spark.apache.org/docs/latest/ml-features.html#locality-sensitive-hashing

 

Pandas怎样对每个分组应用apply函数?

Pandas怎样对每个分组应用apply函数?

知识:Pandas的GroupBy遵从split、apply、combine模式

这里的split指的是pandas的groupby,我们自己实现apply函数,apply返回的结果由pandas进行combine得到结果

GroupBy.apply(function)

  • function的第一个参数是dataframe
  • function的返回结果,可是dataframe、series、单个值,甚至和输入dataframe完全没关系

本次实例演示:

  1. 怎样对数值列按分组的归一化?
  2. 怎样取每个分组的TOPN数据?

实例1:怎样对数值列按分组的归一化?

将不同范围的数值列进行归一化,映射到[0,1]区间:
* 更容易做数据横向对比,比如价格字段是几百到几千,增幅字段是0到100
* 机器学习模型学的更快性能更好

归一化的公式:

演示:用户对电影评分的归一化

每个用户的评分不同,有的乐观派评分高,有的悲观派评分低,按用户做归一化

import pandas as pd
ratings = pd.read_csv(
    "./datas/movielens-1m/ratings.dat", 
    sep="::",
    engine='python', 
    names="UserID::MovieID::Rating::Timestamp".split("::")
)
ratings.head()
UserIDMovieIDRatingTimestamp
0111935978300760
116613978302109
219143978301968
3134084978300275
4123555978824291
# 实现按照用户ID分组,然后对其中一列归一化
def ratings_norm(df):
    """
    @param df:每个用户分组的dataframe
    """
    min_value = df["Rating"].min()
    max_value = df["Rating"].max()
    df["Rating_norm"] = df["Rating"].apply(
        lambda x: (x-min_value)/(max_value-min_value))
    return df

ratings = ratings.groupby("UserID").apply(ratings_norm)
ratings[ratings["UserID"]==1].head()
UserIDMovieIDRatingTimestampRating_norm
01119359783007601.0
1166139783021090.0
2191439783019680.0
31340849783002750.5
41235559788242911.0

可以看到UserID==1这个用户,Rating==3是他的最低分,是个乐观派,我们归一化到0分;

实例2:怎样取每个分组的TOPN数据?

获取2018年每个月温度最高的2天数据

fpath = "./datas/beijing_tianqi/beijing_tianqi_2018.csv"
df = pd.read_csv(fpath)
# 替换掉温度的后缀℃
df.loc[:, "bWendu"] = df["bWendu"].str.replace("℃", "").astype('int32')
df.loc[:, "yWendu"] = df["yWendu"].str.replace("℃", "").astype('int32')
# 新增一列为月份
df['month'] = df['ymd'].str[:7]
df.head()
ymdbWenduyWendutianqifengxiangfengliaqiaqiInfoaqiLevelmonth
02018-01-013-6晴~多云东北风1-2级5922018-01
12018-01-022-5阴~多云东北风1-2级4912018-01
22018-01-032-5多云北风1-2级2812018-01
32018-01-040-8东北风1-2级2812018-01
42018-01-053-6多云~晴西北风1-2级5012018-01
def getWenduTopN(df, topn):
    """
    这里的df,是每个月份分组group的df
    """
    return df.sort_values(by="bWendu")[["ymd", "bWendu"]][-topn:]

df.groupby("month").apply(getWenduTopN, topn=1).head()
ymdbWendu
month
2018-01182018-01-197
2018-02562018-02-2612
2018-03852018-03-2727
2018-041182018-04-2930
2018-051502018-05-3135

我们看到,grouby的apply函数返回的dataframe,其实和原来的dataframe其实可以完全不一样

视频地址在:
http://www.iqiyi.com/a_19rrhyyqix.html

怎样使用Pandas的map和apply函数?

数据转换函数对比:map、apply、applymap:
1. map:只用于Series,实现每个值->值的映射;
2. apply:用于Series实现每个值的处理,用于Dataframe实现某个轴的Series的处理;
3. applymap:只能用于DataFrame,用于处理该DataFrame的每个元素;

1. map用于Series值的转换

实例:将股票代码英文转换成中文名字

Series.map(dict) or Series.map(function)均可

import pandas as pd
stocks = pd.read_excel('./datas/stocks/互联网公司股票.xlsx')
stocks.head()
日期公司收盘开盘交易量涨跌幅
02019-10-03BIDU104.32102.35104.73101.152.240.02
12019-10-02BIDU102.62100.85103.2499.502.690.01
22019-10-01BIDU102.00102.80103.26101.001.78-0.01
32019-10-03BABA169.48166.65170.18165.0010.390.02
42019-10-02BABA165.77162.82166.88161.9011.600.00
stocks["公司"].unique()
array(['BIDU', 'BABA', 'IQ', 'JD'], dtype=object)
# 公司股票代码到中文的映射,注意这里是小写
dict_company_names = {
    "bidu": "百度",
    "baba": "阿里巴巴",
    "iq": "爱奇艺", 
    "jd": "京东"
}

方法1:Series.map(dict)

stocks["公司中文1"] = stocks["公司"].str.lower().map(dict_company_names)
stocks.head()
日期公司收盘开盘交易量涨跌幅公司中文1
02019-10-03BIDU104.32102.35104.73101.152.240.02百度
12019-10-02BIDU102.62100.85103.2499.502.690.01百度
22019-10-01BIDU102.00102.80103.26101.001.78-0.01百度
32019-10-03BABA169.48166.65170.18165.0010.390.02阿里巴巴
42019-10-02BABA165.77162.82166.88161.9011.600.00阿里巴巴

方法2:Series.map(function)

function的参数是Series的每个元素的值

stocks["公司中文2"] = stocks["公司"].map(lambda x : dict_company_names[x.lower()])
stocks.head()
日期公司收盘开盘交易量涨跌幅公司中文1公司中文2
02019-10-03BIDU104.32102.35104.73101.152.240.02百度百度
12019-10-02BIDU102.62100.85103.2499.502.690.01百度百度
22019-10-01BIDU102.00102.80103.26101.001.78-0.01百度百度
32019-10-03BABA169.48166.65170.18165.0010.390.02阿里巴巴阿里巴巴
42019-10-02BABA165.77162.82166.88161.9011.600.00阿里巴巴阿里巴巴

2. apply用于Series和DataFrame的转换

  • Series.apply(function), 函数的参数是每个值
  • DataFrame.apply(function), 函数的参数是Series

Series.apply(function)

function的参数是Series的每个值

stocks["公司中文3"] = stocks["公司"].apply(
    lambda x : dict_company_names[x.lower()])
stocks.head()
日期公司收盘开盘交易量涨跌幅公司中文1公司中文2公司中文3
02019-10-03BIDU104.32102.35104.73101.152.240.02百度百度百度
12019-10-02BIDU102.62100.85103.2499.502.690.01百度百度百度
22019-10-01BIDU102.00102.80103.26101.001.78-0.01百度百度百度
32019-10-03BABA169.48166.65170.18165.0010.390.02阿里巴巴阿里巴巴阿里巴巴
42019-10-02BABA165.77162.82166.88161.9011.600.00阿里巴巴阿里巴巴阿里巴巴

DataFrame.apply(function)

function的参数是对应轴的Series

stocks["公司中文4"] = stocks.apply(
    lambda x : dict_company_names[x["公司"].lower()], 
    axis=1)

注意这个代码:
1、apply是在stocks这个DataFrame上调用;
2、lambda x的x是一个Series,因为指定了axis=1所以Seires的key是列名,可以用x[‘公司’]获取

stocks.head()
日期公司收盘开盘交易量涨跌幅公司中文1公司中文2公司中文3公司中文4
02019-10-03BIDU104.32102.35104.73101.152.240.02百度百度百度百度
12019-10-02BIDU102.62100.85103.2499.502.690.01百度百度百度百度
22019-10-01BIDU102.00102.80103.26101.001.78-0.01百度百度百度百度
32019-10-03BABA169.48166.65170.18165.0010.390.02阿里巴巴阿里巴巴阿里巴巴阿里巴巴
42019-10-02BABA165.77162.82166.88161.9011.600.00阿里巴巴阿里巴巴阿里巴巴阿里巴巴

3. applymap用于DataFrame所有值的转换

sub_df = stocks[['收盘', '开盘', '高', '低', '交易量']]
sub_df.head()
收盘开盘交易量
0104.32102.35104.73101.152.24
1102.62100.85103.2499.502.69
2102.00102.80103.26101.001.78
3169.48166.65170.18165.0010.39
4165.77162.82166.88161.9011.60
# 将这些数字取整数,应用于所有元素
sub_df.applymap(lambda x : int(x))
收盘开盘交易量
01041021041012
1102100103992
21021021031011
316916617016510
416516216616111
516516816816314
61615161510
7151515158
81516161511
9282828278
10282828279
112828282710
# 直接修改原df的这几列
stocks.loc[:, ['收盘', '开盘', '高', '低', '交易量']] = sub_df.applymap(lambda x : int(x))
stocks.head()
日期公司收盘开盘交易量涨跌幅公司中文1公司中文2公司中文3公司中文4
02019-10-03BIDU10410210410120.02百度百度百度百度
12019-10-02BIDU1021001039920.01百度百度百度百度
22019-10-01BIDU1021021031011-0.01百度百度百度百度
32019-10-03BABA169166170165100.02阿里巴巴阿里巴巴阿里巴巴阿里巴巴
42019-10-02BABA165162166161110.00阿里巴巴阿里巴巴阿里巴巴阿里巴巴

Pandas的分层索引MultiIndex怎样用?

Pandas的分层索引MultiIndex

为什么要学习分层索引MultiIndex?
* 分层索引:在一个轴向上拥有多个索引层级,可以表达更高维度数据的形式;
* 可以更方便的进行数据筛选,如果有序则性能更好;
* groupby等操作的结果,如果是多KEY,结果是分层索引,需要会使用
* 一般不需要自己创建分层索引(MultiIndex有构造函数但一般不用)

演示数据:百度、阿里巴巴、爱奇艺、京东四家公司的10天股票数据
数据来自:英为财经
https://cn.investing.com/

本次演示提纲:
一、Series的分层索引MultiIndex
二、Series有多层索引怎样筛选数据?
三、DataFrame的多层索引MultiIndex
四、DataFrame有多层索引怎样筛选数据?

import pandas as pd
%matplotlib inline
stocks = pd.read_excel('./datas/stocks/互联网公司股票.xlsx')
stocks.shape
(12, 8)
stocks.head(3)
日期公司收盘开盘交易量涨跌幅
02019-10-03BIDU104.32102.35104.73101.152.240.02
12019-10-02BIDU102.62100.85103.2499.502.690.01
22019-10-01BIDU102.00102.80103.26101.001.78-0.01
stocks["公司"].unique()
array(['BIDU', 'BABA', 'IQ', 'JD'], dtype=object)
stocks.index
RangeIndex(start=0, stop=12, step=1)
stocks.groupby('公司')["收盘"].mean()
公司
BABA    166.80
BIDU    102.98
IQ       15.90
JD       28.35
Name: 收盘, dtype: float64

一、Series的分层索引MultiIndex

ser = stocks.groupby(['公司', '日期'])['收盘'].mean()
ser
公司    日期        
BABA  2019-10-01    165.15
      2019-10-02    165.77
      2019-10-03    169.48
BIDU  2019-10-01    102.00
      2019-10-02    102.62
      2019-10-03    104.32
IQ    2019-10-01     15.92
      2019-10-02     15.72
      2019-10-03     16.06
JD    2019-10-01     28.19
      2019-10-02     28.06
      2019-10-03     28.80
Name: 收盘, dtype: float64

多维索引中,空白的意思是:使用上面的值

ser.index
MultiIndex([('BABA', '2019-10-01'),
            ('BABA', '2019-10-02'),
            ('BABA', '2019-10-03'),
            ('BIDU', '2019-10-01'),
            ('BIDU', '2019-10-02'),
            ('BIDU', '2019-10-03'),
            (  'IQ', '2019-10-01'),
            (  'IQ', '2019-10-02'),
            (  'IQ', '2019-10-03'),
            (  'JD', '2019-10-01'),
            (  'JD', '2019-10-02'),
            (  'JD', '2019-10-03')],
           names=['公司', '日期'])
# unstack把二级索引变成列
ser.unstack()
日期2019-10-012019-10-022019-10-03
公司
BABA165.15165.77169.48
BIDU102.00102.62104.32
IQ15.9215.7216.06
JD28.1928.0628.80
ser
公司    日期        
BABA  2019-10-01    165.15
      2019-10-02    165.77
      2019-10-03    169.48
BIDU  2019-10-01    102.00
      2019-10-02    102.62
      2019-10-03    104.32
IQ    2019-10-01     15.92
      2019-10-02     15.72
      2019-10-03     16.06
JD    2019-10-01     28.19
      2019-10-02     28.06
      2019-10-03     28.80
Name: 收盘, dtype: float64
ser.reset_index()
公司日期收盘
0BABA2019-10-01165.15
1BABA2019-10-02165.77
2BABA2019-10-03169.48
3BIDU2019-10-01102.00
4BIDU2019-10-02102.62
5BIDU2019-10-03104.32
6IQ2019-10-0115.92
7IQ2019-10-0215.72
8IQ2019-10-0316.06
9JD2019-10-0128.19
10JD2019-10-0228.06
11JD2019-10-0328.80

二、Series有多层索引MultiIndex怎样筛选数据?

ser
公司    日期        
BABA  2019-10-01    165.15
      2019-10-02    165.77
      2019-10-03    169.48
BIDU  2019-10-01    102.00
      2019-10-02    102.62
      2019-10-03    104.32
IQ    2019-10-01     15.92
      2019-10-02     15.72
      2019-10-03     16.06
JD    2019-10-01     28.19
      2019-10-02     28.06
      2019-10-03     28.80
Name: 收盘, dtype: float64
ser.loc['BIDU']
日期
2019-10-01    102.00
2019-10-02    102.62
2019-10-03    104.32
Name: 收盘, dtype: float64
# 多层索引,可以用元组的形式筛选
ser.loc[('BIDU', '2019-10-02')]
102.62
ser.loc[:, '2019-10-02']
公司
BABA    165.77
BIDU    102.62
IQ       15.72
JD       28.06
Name: 收盘, dtype: float64

三、DataFrame的多层索引MultiIndex

stocks.head()
日期公司收盘开盘交易量涨跌幅
02019-10-03BIDU104.32102.35104.73101.152.240.02
12019-10-02BIDU102.62100.85103.2499.502.690.01
22019-10-01BIDU102.00102.80103.26101.001.78-0.01
32019-10-03BABA169.48166.65170.18165.0010.390.02
42019-10-02BABA165.77162.82166.88161.9011.600.00
stocks.set_index(['公司', '日期'], inplace=True)
stocks
收盘开盘交易量涨跌幅
公司日期
BIDU2019-10-03104.32102.35104.73101.152.240.02
2019-10-02102.62100.85103.2499.502.690.01
2019-10-01102.00102.80103.26101.001.78-0.01
BABA2019-10-03169.48166.65170.18165.0010.390.02
2019-10-02165.77162.82166.88161.9011.600.00
2019-10-01165.15168.01168.23163.6414.19-0.01
IQ2019-10-0316.0615.7116.3815.3210.080.02
2019-10-0215.7215.8515.8715.128.10-0.01
2019-10-0115.9216.1416.2215.5011.65-0.01
JD2019-10-0328.8028.1128.9727.828.770.03
2019-10-0228.0628.0028.2227.539.530.00
2019-10-0128.1928.2228.5727.9710.640.00
stocks.index
MultiIndex([('BIDU', '2019-10-03'),
            ('BIDU', '2019-10-02'),
            ('BIDU', '2019-10-01'),
            ('BABA', '2019-10-03'),
            ('BABA', '2019-10-02'),
            ('BABA', '2019-10-01'),
            (  'IQ', '2019-10-03'),
            (  'IQ', '2019-10-02'),
            (  'IQ', '2019-10-01'),
            (  'JD', '2019-10-03'),
            (  'JD', '2019-10-02'),
            (  'JD', '2019-10-01')],
           names=['公司', '日期'])
stocks.sort_index(inplace=True)
stocks
收盘开盘交易量涨跌幅
公司日期
BABA2019-10-01165.15168.01168.23163.6414.19-0.01
2019-10-02165.77162.82166.88161.9011.600.00
2019-10-03169.48166.65170.18165.0010.390.02
BIDU2019-10-01102.00102.80103.26101.001.78-0.01
2019-10-02102.62100.85103.2499.502.690.01
2019-10-03104.32102.35104.73101.152.240.02
IQ2019-10-0115.9216.1416.2215.5011.65-0.01
2019-10-0215.7215.8515.8715.128.10-0.01
2019-10-0316.0615.7116.3815.3210.080.02
JD2019-10-0128.1928.2228.5727.9710.640.00
2019-10-0228.0628.0028.2227.539.530.00
2019-10-0328.8028.1128.9727.828.770.03

四、DataFrame有多层索引MultiIndex怎样筛选数据?

重要知识】在选择数据时:
* 元组(key1,key2)代表筛选多层索引,其中key1是索引第一级,key2是第二级,比如key1=JD, key2=2019-10-02
* 列表[key1,key2]代表同一层的多个KEY,其中key1和key2是并列的同级索引,比如key1=JD, key2=BIDU

stocks.loc['BIDU']
收盘开盘交易量涨跌幅
日期
2019-10-01102.00102.80103.26101.001.78-0.01
2019-10-02102.62100.85103.2499.502.690.01
2019-10-03104.32102.35104.73101.152.240.02
stocks.loc[('BIDU', '2019-10-02'), :]
收盘     102.62
开盘     100.85
高      103.24
低       99.50
交易量      2.69
涨跌幅      0.01
Name: (BIDU, 2019-10-02), dtype: float64
stocks.loc[('BIDU', '2019-10-02'), '开盘']
100.85
stocks.loc[['BIDU', 'JD'], :]
收盘开盘交易量涨跌幅
公司日期
BIDU2019-10-01102.00102.80103.26101.001.78-0.01
2019-10-02102.62100.85103.2499.502.690.01
2019-10-03104.32102.35104.73101.152.240.02
JD2019-10-0128.1928.2228.5727.9710.640.00
2019-10-0228.0628.0028.2227.539.530.00
2019-10-0328.8028.1128.9727.828.770.03
stocks.loc[(['BIDU', 'JD'], '2019-10-03'), :]
收盘开盘交易量涨跌幅
公司日期
BIDU2019-10-03104.32102.35104.73101.152.240.02
JD2019-10-0328.8028.1128.9727.828.770.03
stocks.loc[(['BIDU', 'JD'], '2019-10-03'), '收盘']
公司    日期        
BIDU  2019-10-03    104.32
JD    2019-10-03     28.80
Name: 收盘, dtype: float64
stocks.loc[('BIDU', ['2019-10-02', '2019-10-03']), '收盘']
公司    日期        
BIDU  2019-10-02    102.62
      2019-10-03    104.32
Name: 收盘, dtype: float64
# slice(None)代表筛选这一索引的所有内容
stocks.loc[(slice(None), ['2019-10-02', '2019-10-03']), :]
收盘开盘交易量涨跌幅
公司日期
BABA2019-10-02165.77162.82166.88161.9011.600.00
2019-10-03169.48166.65170.18165.0010.390.02
BIDU2019-10-02102.62100.85103.2499.502.690.01
2019-10-03104.32102.35104.73101.152.240.02
IQ2019-10-0215.7215.8515.8715.128.10-0.01
2019-10-0316.0615.7116.3815.3210.080.02
JD2019-10-0228.0628.0028.2227.539.530.00
2019-10-0328.8028.1128.9727.828.770.03
stocks.reset_index()
公司日期收盘开盘交易量涨跌幅
0BABA2019-10-01165.15168.01168.23163.6414.19-0.01
1BABA2019-10-02165.77162.82166.88161.9011.600.00
2BABA2019-10-03169.48166.65170.18165.0010.390.02
3BIDU2019-10-01102.00102.80103.26101.001.78-0.01
4BIDU2019-10-02102.62100.85103.2499.502.690.01
5BIDU2019-10-03104.32102.35104.73101.152.240.02
6IQ2019-10-0115.9216.1416.2215.5011.65-0.01
7IQ2019-10-0215.7215.8515.8715.128.10-0.01
8IQ2019-10-0316.0615.7116.3815.3210.080.02
9JD2019-10-0128.1928.2228.5727.9710.640.00
10JD2019-10-0228.0628.0028.2227.539.530.00
11JD2019-10-0328.8028.1128.9727.828.770.03

转载请注明链接: http://www.crazyant.net/2598.html

Pandas怎样实现对数据的分组统计?

Pandas怎样实现groupby分组统计

类似SQL:
select city,max(temperature) from city_weather group by city;

groupby:先对数据分组,然后在每个分组上应用聚合函数、转换函数

本次演示:
一、分组使用聚合函数做数据统计
二、遍历groupby的结果理解执行流程
三、实例分组探索天气数据

import pandas as pd
import numpy as np
# 加上这一句,能在jupyter notebook展示matplot图表
%matplotlib inline
df = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],
                   'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
                   'C': np.random.randn(8),
                   'D': np.random.randn(8)})
df
ABCD
0fooone0.5429030.788896
1barone-0.375789-0.345869
2footwo-0.9034070.428031
3barthree-1.5647480.081163
4footwo-1.0936020.837348
5bartwo-0.2024030.701301
6fooone-0.665189-1.505290
7foothree-0.4983390.534438

一、分组使用聚合函数做数据统计

1、单个列groupby,查询所有数据列的统计

df.groupby('A').sum()
CD
A
bar-2.1429400.436595
foo-2.6176331.083423

我们看到:
1. groupby中的’A’变成了数据的索引列
2. 因为要统计sum,但B列不是数字,所以被自动忽略掉

2、多个列groupby,查询所有数据列的统计

df.groupby(['A','B']).mean()
CD
AB
barone-0.375789-0.345869
three-1.5647480.081163
two-0.2024030.701301
fooone-0.061143-0.358197
three-0.4983390.534438
two-0.9985040.632690

我们看到:(‘A’,’B’)成对变成了二级索引

df.groupby(['A','B'], as_index=False).mean()
ABCD
0barone-0.375789-0.345869
1barthree-1.5647480.081163
2bartwo-0.2024030.701301
3fooone-0.061143-0.358197
4foothree-0.4983390.534438
5footwo-0.9985040.632690

3、同时查看多种数据统计

df.groupby('A').agg([np.sum, np.mean, np.std])
CD
summeanstdsummeanstd
A
bar-2.142940-0.7143130.7415830.4365950.1455320.526544
foo-2.617633-0.5235270.6378221.0834230.2166850.977686

我们看到:列变成了多级索引

4、查看单列的结果数据统计

# 方法1:预过滤,性能更好
df.groupby('A')['C'].agg([np.sum, np.mean, np.std])
summeanstd
A
bar-2.142940-0.7143130.741583
foo-2.617633-0.5235270.637822
# 方法2
df.groupby('A').agg([np.sum, np.mean, np.std])['C']
summeanstd
A
bar-2.142940-0.7143130.741583
foo-2.617633-0.5235270.637822

5、不同列使用不同的聚合函数

df.groupby('A').agg({"C":np.sum, "D":np.mean})
CD
A
bar-2.1429400.145532
foo-2.6176330.216685

二、遍历groupby的结果理解执行流程

for循环可以直接遍历每个group

1、遍历单个列聚合的分组
g = df.groupby('A')
g
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x00000123B250E548>
for name,group in g:
    print(name)
    print(group)
    print()
bar
     A      B         C         D
1  bar    one -0.375789 -0.345869
3  bar  three -1.564748  0.081163
5  bar    two -0.202403  0.701301

foo
     A      B         C         D
0  foo    one  0.542903  0.788896
2  foo    two -0.903407  0.428031
4  foo    two -1.093602  0.837348
6  foo    one -0.665189 -1.505290
7  foo  three -0.498339  0.534438

可以获取单个分组的数据

g.get_group('bar')
ABCD
1barone-0.375789-0.345869
3barthree-1.5647480.081163
5bartwo-0.2024030.701301
2、遍历多个列聚合的分组
g = df.groupby(['A', 'B'])
for name,group in g:
    print(name)
    print(group)
    print()
('bar', 'one')
     A    B         C         D
1  bar  one -0.375789 -0.345869

('bar', 'three')
     A      B         C         D
3  bar  three -1.564748  0.081163

('bar', 'two')
     A    B         C         D
5  bar  two -0.202403  0.701301

('foo', 'one')
     A    B         C         D
0  foo  one  0.542903  0.788896
6  foo  one -0.665189 -1.505290

('foo', 'three')
     A      B         C         D
7  foo  three -0.498339  0.534438

('foo', 'two')
     A    B         C         D
2  foo  two -0.903407  0.428031
4  foo  two -1.093602  0.837348

可以看到,name是一个2个元素的tuple,代表不同的列

g.get_group(('foo', 'one'))
ABCD
0fooone0.5429030.788896
6fooone-0.665189-1.505290

可以直接查询group后的某几列,生成Series或者子DataFrame

g['C']
<pandas.core.groupby.generic.SeriesGroupBy object at 0x00000123C33F64C8>
for name, group in g['C']:
    print(name)
    print(group)
    print(type(group))
    print()
('bar', 'one')
1   -0.375789
Name: C, dtype: float64
<class 'pandas.core.series.Series'>

('bar', 'three')
3   -1.564748
Name: C, dtype: float64
<class 'pandas.core.series.Series'>

('bar', 'two')
5   -0.202403
Name: C, dtype: float64
<class 'pandas.core.series.Series'>

('foo', 'one')
0    0.542903
6   -0.665189
Name: C, dtype: float64
<class 'pandas.core.series.Series'>

('foo', 'three')
7   -0.498339
Name: C, dtype: float64
<class 'pandas.core.series.Series'>

('foo', 'two')
2   -0.903407
4   -1.093602
Name: C, dtype: float64
<class 'pandas.core.series.Series'>

其实所有的聚合统计,都是在dataframe和series上进行的;

三、实例分组探索天气数据

fpath = "./datas/beijing_tianqi/beijing_tianqi_2018.csv"
df = pd.read_csv(fpath)
# 替换掉温度的后缀℃
df.loc[:, "bWendu"] = df["bWendu"].str.replace("℃", "").astype('int32')
df.loc[:, "yWendu"] = df["yWendu"].str.replace("℃", "").astype('int32')
df.head()
ymdbWenduyWendutianqifengxiangfengliaqiaqiInfoaqiLevel
02018-01-013-6晴~多云东北风1-2级592
12018-01-022-5阴~多云东北风1-2级491
22018-01-032-5多云北风1-2级281
32018-01-040-8东北风1-2级281
42018-01-053-6多云~晴西北风1-2级501
# 新增一列为月份
df['month'] = df['ymd'].str[:7]
df.head()
ymdbWenduyWendutianqifengxiangfengliaqiaqiInfoaqiLevelmonth
02018-01-013-6晴~多云东北风1-2级5922018-01
12018-01-022-5阴~多云东北风1-2级4912018-01
22018-01-032-5多云北风1-2级2812018-01
32018-01-040-8东北风1-2级2812018-01
42018-01-053-6多云~晴西北风1-2级5012018-01

1、查看每个月的最高温度

data = df.groupby('month')['bWendu'].max()
data
month
2018-01     7
2018-02    12
2018-03    27
2018-04    30
2018-05    35
2018-06    38
2018-07    37
2018-08    36
2018-09    31
2018-10    25
2018-11    18
2018-12    10
Name: bWendu, dtype: int32
type(data)
pandas.core.series.Series
data.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x123c344b308>

2、查看每个月的最高温度、最低温度、平均空气质量指数

df.head()
ymdbWenduyWendutianqifengxiangfengliaqiaqiInfoaqiLevelmonth
02018-01-013-6晴~多云东北风1-2级5922018-01
12018-01-022-5阴~多云东北风1-2级4912018-01
22018-01-032-5多云北风1-2级2812018-01
32018-01-040-8东北风1-2级2812018-01
42018-01-053-6多云~晴西北风1-2级5012018-01
group_data = df.groupby('month').agg({"bWendu":np.max, "yWendu":np.min, "aqi":np.mean})
group_data
bWenduyWenduaqi
month
2018-017-1260.677419
2018-0212-1078.857143
2018-0327-4130.322581
2018-04301102.866667
2018-05351099.064516
2018-06381782.300000
2018-07372272.677419
2018-08362059.516129
2018-09311150.433333
2018-1025167.096774
2018-1118-4105.100000
2018-1210-1277.354839
group_data.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x123c5502d48>


怎样使用Pandas批量拆分与合并Excel文件?

Pandas批量拆分Excel与合并Excel

实例演示:
1. 将一个大Excel等份拆成多个Excel
2. 将多个小Excel合并成一个大Excel并标记来源

work_dir="./course_datas/c15_excel_split_merge"
splits_dir=f"{work_dir}/splits"

import os
if not os.path.exists(splits_dir):
    os.mkdir(splits_dir)

0、读取源Excel到Pandas

import pandas as pd
df_source = pd.read_excel(f"{work_dir}/crazyant_blog_articles_source.xlsx")
df_source.head()
idtitletags
02585Tensorflow怎样接收变长列表特征python,tensorflow,特征工程
12583Pandas实现数据的合并concatpandas,python,数据分析
22574Pandas的Index索引有什么用途?pandas,python,数据分析
32564机器学习常用数据集大全python,机器学习
42561一个数据科学家的修炼路径数据分析
df_source.index
RangeIndex(start=0, stop=258, step=1)
df_source.shape
(258, 3)
total_row_count = df_source.shape[0]
total_row_count
258

一、将一个大Excel等份拆成多个Excel

  1. 使用df.iloc方法,将一个大的dataframe,拆分成多个小dataframe
  2. 将使用dataframe.to_excel保存每个小Excel

1、计算拆分后的每个excel的行数

# 这个大excel,会拆分给这几个人
user_names = ["xiao_shuai", "xiao_wang", "xiao_ming", "xiao_lei", "xiao_bo", "xiao_hong"]
# 每个人的任务数目
split_size = total_row_count // len(user_names)
if total_row_count % len(user_names) != 0:
    split_size += 1

split_size
43

2、拆分成多个dataframe

df_subs = []
for idx, user_name in enumerate(user_names):
    # iloc的开始索引
    begin = idx*split_size
    # iloc的结束索引
    end = begin+split_size
    # 实现df按照iloc拆分
    df_sub = df_source.iloc[begin:end]
    # 将每个子df存入列表
    df_subs.append((idx, user_name, df_sub))

3、将每个datafame存入excel

for idx, user_name, df_sub in df_subs:
    file_name = f"{splits_dir}/crazyant_blog_articles_{idx}_{user_name}.xlsx"
    df_sub.to_excel(file_name, index=False)

二、合并多个小Excel到一个大Excel

  1. 遍历文件夹,得到要合并的Excel文件列表
  2. 分别读取到dataframe,给每个df添加一列用于标记来源
  3. 使用pd.concat进行df批量合并
  4. 将合并后的dataframe输出到excel

1. 遍历文件夹,得到要合并的Excel名称列表

import os
excel_names = []
for excel_name in os.listdir(splits_dir):
    excel_names.append(excel_name)
excel_names
['crazyant_blog_articles_0_xiao_shuai.xlsx',
 'crazyant_blog_articles_1_xiao_wang.xlsx',
 'crazyant_blog_articles_2_xiao_ming.xlsx',
 'crazyant_blog_articles_3_xiao_lei.xlsx',
 'crazyant_blog_articles_4_xiao_bo.xlsx',
 'crazyant_blog_articles_5_xiao_hong.xlsx']

2. 分别读取到dataframe

df_list = []

for excel_name in excel_names:
    # 读取每个excel到df
    excel_path = f"{splits_dir}/{excel_name}"
    df_split = pd.read_excel(excel_path)
    # 得到username
    username = excel_name.replace("crazyant_blog_articles_", "").replace(".xlsx", "")[2:]
    print(excel_name, username)
    # 给每个df添加1列,即用户名字
    df_split["username"] = username

    df_list.append(df_split)
crazyant_blog_articles_0_xiao_shuai.xlsx xiao_shuai
crazyant_blog_articles_1_xiao_wang.xlsx xiao_wang
crazyant_blog_articles_2_xiao_ming.xlsx xiao_ming
crazyant_blog_articles_3_xiao_lei.xlsx xiao_lei
crazyant_blog_articles_4_xiao_bo.xlsx xiao_bo
crazyant_blog_articles_5_xiao_hong.xlsx xiao_hong

3. 使用pd.concat进行合并

df_merged = pd.concat(df_list)
df_merged.shape
(258, 4)
df_merged.head()
idtitletagsusername
02585Tensorflow怎样接收变长列表特征python,tensorflow,特征工程xiao_shuai
12583Pandas实现数据的合并concatpandas,python,数据分析xiao_shuai
22574Pandas的Index索引有什么用途?pandas,python,数据分析xiao_shuai
32564机器学习常用数据集大全python,机器学习xiao_shuai
42561一个数据科学家的修炼路径数据分析xiao_shuai
df_merged["username"].value_counts()
xiao_hong     43
xiao_bo       43
xiao_shuai    43
xiao_lei      43
xiao_wang     43
xiao_ming     43
Name: username, dtype: int64

4. 将合并后的dataframe输出到excel

df_merged.to_excel(f"{work_dir}/crazyant_blog_articles_merged.xlsx", index=False)

Tensorflow怎样接收变长列表特征

比如用户的分类偏好、用户的历史观影行为,都是变长的元素列表,怎么输入到模型?

这个问题很多人遇到,比如这些:

有几种方法,但都还没有完美解决问题:

1、multi-onehot

自己创建一个大数组,把变长元素对应位置设置为1;

比如这个特征有两个值:
值1:a、b、c
值2:b、c、d
那么词表是a、b、c、d
值1就变成了[1,1,1,0],值2变成了[0,1,1,1]

这种方式最灵活,因为如果遇到了带有权重的分类列表,也能搞定:
比如
值1:[(a,0.8), (b,0.7), (c, 0.6)]
值2:[(b,0.5), (c, 0.4), (d, 0.3)]
那么词表依然是a、b、c、d,但是对应权重却可以放到原来为1的位置上;
值1变成了:[0.8, 0.7, 0.6, 0]
值2变成了:[0, 0.5, 0.4, 0.3]

然而这种方法tensorflow的feature column不支持,只能自己做映射转换

2、变成定长

以下两种方式,tensorflow的feature column可以支持

变成定长方法1:截取前TOP N个元素

来自资料:
http://proceedings.mlr.press/v7/niculescu09
有个PDF,看截图:

使用的方法,是先计算每个词语的频率,然后去TOP10的频率;

对于这种方法,个人感觉,如果是用户的分类偏好(分类,权重)列表,可以按照权重排序,取TOP10;
也可以提取定长10个元素,并且反映了用户个性化的偏好;

变成定长方法2:使用padding补0

来自资料:tensorflow的官方文档
https://www.tensorflow.org/tutorials/text/text_classification_rnn

这是用0补齐的方式;