前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[编程经验] Pandas中比较好用的几个方法

[编程经验] Pandas中比较好用的几个方法

作者头像
用户1622570
发布2018-04-11 16:16:41
1.8K0
发布2018-04-11 16:16:41
举报
文章被收录于专栏:机器学习和数学

话说我现在好久不做深度学习的东西了,做了一段时间是的NLP,以为可以去尝试各种高大上的算法,然而现在还并没有,反而觉得更像是做数据挖掘的。。平时遇到的比较多的问题,大多数都是数据清洗的工作,这时候工具就显得很重要,有一个好的工具能起到事半功倍的效果,比如突然有个idea,然后自己开始呼哧呼哧的造轮子,最后才发现,哦,原来都有现成的方法,本来一行代码就可以搞定的问题,到最后写了几十行。 正所谓,“欲闪其事,必先利其器”啊。 好了,废话不多说,下面介绍几个神奇的方法。

  1. 数据筛选

先把数据导入进来,数据一共有4列,分别是日期,星期,品牌和数量,一共有14行数据。

代码语言:javascript
复制
import pandas as pd

data = pd.read_table("test.txt")
print(data.head(2))
print(data.shape)
"""
   日期  星期  品牌  数量
    0   1   3   1  20
    1   1   3   5  48
(14, 4)
"""

然后我们可以查看一下品牌列有几种可能,看到有1,2,3,4,5一共五种品牌。

代码语言:javascript
复制
brand = data['品牌']
print(set(brand.values.tolist()))

"""
{1, 2, 3, 4, 5}
"""

好,如果我现在想查看品牌1的数据,怎么做呢。可以这样

代码语言:javascript
复制
brand_1 = data[data['品牌'].isin([1])]
print(brand_1)
"""
   日期  星期  品牌    数量
0   1   3   1    20
2   2   4   1    16
4   3   5   1  1411
9   4   6   1  1176
"""

看一下,这里用了isin()方法,这样就得到了品牌1的全部数据,可能也有人说,还有一种做法,就是用Groupby,好,Groupby是pandas中用来做分组统计的方法。不知道?没关系,下面介绍

这里还有要2件事情,可不可以查看多个品牌的数据?可以,这样做就行了

代码语言:javascript
复制
brand_n = data[data['品牌'].isin([1, 2])]
print(brand_n)
"""
    日期  星期  品牌    数量
0    1   3   1    20
2    2   4   1    16
4    3   5   1  1411
5    3   5   2   811
9    4   6   1  1176
10   4   6   2   824
"""

isin()方法传入的是一个list就可以,好,如果我想查看除了品牌1以外的数据,怎么做? 用pandas 很简单。这样就可以

代码语言:javascript
复制
brand_ex_1 = data[~data['品牌'].isin([1])]
print(brand_ex_1)
"""
    日期  星期  品牌    数量
1    1   3   5    48
3    2   4   3    20
5    3   5   2   811
6    3   5   3  1005
7    3   5   4   773
8    3   5   5  1565
10   4   6   2   824
11   4   6   3   802
12   4   6   4  1057
13   4   6   5  1107
"""

2 . 数据分组

好,然后说一下,groupby,groupby就是group data by xx。按照xx把数据分为几个组。先看个栗子,首先把数据按日期分组。

代码语言:javascript
复制
data_grouped = data.groupby(by='日期')
print("共有 {} 组".format(data_grouped.ngroups))
# 共有 4 组

print(data_grouped.ngroup(ascending=True))
"""
0     3
1     3
2     2
3     2
4     1
5     1
6     1
7     1
8     1
9     0
10    0
11    0
12    0
13    0
"""

查看分组后的索引

代码语言:javascript
复制
indices = data_grouped.indices
day_1 = indices[3]
print(day_1)
"""
[4 5 6 7 8]
"""

还可以这样

代码语言:javascript
复制
for i, j in data_grouped:
    print(i, j.index)
"""
1 Int64Index([0, 1], dtype='int64')
2 Int64Index([2, 3], dtype='int64')
3 Int64Index([4, 5, 6, 7, 8], dtype='int64')
4 Int64Index([9, 10, 11, 12, 13], dtype='int64')
"""

分组之后的数据还是一个DataFrame对象,所以可以调用index方法。

如果要对分组后的数据做统计分析,可以这样来做

代码语言:javascript
复制
import pandas as pd

data = pd.read_table("test.txt")
data_grouped = data.groupby(by='日期')['数量'].mean()

print(data_grouped)

这样就可以查看每一天数量的平均值了。

3. appy方法

如果我想给数量这一列,每个值都乘以2,可以怎么做呢? 方法很多,这里介绍一下,如何用apply来做,

代码语言:javascript
复制
import pandas as pd

data = pd.read_table("test.txt")


def double_df(x):
    return 2 * x


data_double = data['数量'].apply(double_df)
print(data_double)
"""
0       40
1       96
2       32
3       40
4     2822
5     1622
6     2010
7     1546
8     3130
9     2352
10    1648
11    1604
12    2114
13    2214
Name: 数量, dtype: int64
"""

这样就可以很简单的完成这个倍乘的任务,但是输出貌似不是我们想要的,因为我们还想保留其他列,那应该怎么做呢。

代码语言:javascript
复制
import pandas as pd

data = pd.read_table("test.txt")


def double_df(x):
    return 2 * x

data_copy = data.copy()
data_copy['数量'] = data['数量'].apply(double_df)
print(data_copy)
"""
    日期  星期  品牌    数量
0    1   3   1    40
1    1   3   5    96
2    2   4   1    32
3    2   4   3    40
4    3   5   1  2822
5    3   5   2  1622
6    3   5   3  2010
7    3   5   4  1546
8    3   5   5  3130
9    4   6   1  2352
10   4   6   2  1648
11   4   6   3  1604
12   4   6   4  2114
13   4   6   5  2214
"""

这里可以先复制一份data, 然后给复制的数据中的“数量”这一列用data中数量的列apply函数,这样就不会有数据损失了。

好,这是apply的基本应用,如果我们想对两列数据使用apply函数,应该怎么做。开始我也不会,那天突然有这样的想法,因为我的数据是在两列都有,然后我想统计两列的性质,无奈不知道怎么用,然后在stackflow上找到了答案。这里分享给大家

代码语言:javascript
复制
def double_df(a, b):
    return "{:.03f}".format(a / b)

data_apply = data.apply(lambda row: 
                        double_df(row['星期'],
                                  row['品牌']),
                        axis=1)
print(data_apply)
"""
0     3.000
1     0.600
2     4.000
3     1.333
4     5.000
5     2.500
6     1.667
7     1.250
8     1.000
9     6.000
10    3.000
11    2.000
12    1.500
13    1.200
dtype: object

"""

或者这样

代码语言:javascript
复制
def double_df(rows):
    return "{:.03f}".format(rows['星期'] / rows['品牌'])

data_apply = data.apply(double_df, axis=1)
print(data_apply)
"""
0     3.000
1     0.600
2     4.000
3     1.333
4     5.000
5     2.500
6     1.667
7     1.250
8     1.000
9     6.000
10    3.000
11    2.000
12    1.500
13    1.200
dtype: object

"""

同样,你要是想的到原始的全部数据,最好复制一份,不然可能会报错,有兴趣可以去试试。

4. 删除Pandas中的NaN和空格

对于缺失数据的处理,无非两种方法,一种是直接删掉不要了,一种是添加进去一些别的数据,那Pandas怎么删除缺失值?本来Pandas提供了dropna方法,直接一个方法就搞定了,但是有时候缺失值不是Nan,而是空格或者别的什么,死活删不掉,我就遇到过,然后折腾啊折腾,一直报ValueError的错误,但是我明明用了dropna了,说明数据还是没有清洗干净。好,下面这个方法,是我搜集到的网上现有的三种删除缺失值的方法,可以直接用。

代码语言:javascript
复制
def delet_pandas_na(in_df, columns_name, method='one'):
    if method == 'one':
        out_df = in_df.copy()
        out_df[columns_name] = \
            in_df[columns_name].apply(
              lambda x: np.NaN if len(str(x)) < 1 else x)
      out_df_res = out_df[out_df[columns_name].notnull()]
        return out_df_res

    elif method == 'two':
        out_df = (in_df[columns_name].isnull()) | \
                 (in_df[columns_name].apply(
                     lambda x: str(x).isspace()))
        out_df_res = in_df[~out_df]
        return out_df_res
    else:
        in_df.dropna(inplace=True)
        indices_to_keep = ~in_df.isin([np.nan,
                                       np.inf,
                                       -np.inf]).any(1)
        return in_df[indices_to_keep].astype(np.float64)

好了。有什么不明白的,随时可以问我。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-01-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 机器学习和数学 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档