900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > pandas 提取大于某值的数据_Pandas 数据处理(二) - 筛选数据

pandas 提取大于某值的数据_Pandas 数据处理(二) - 筛选数据

时间:2021-11-11 20:25:48

相关推荐

pandas 提取大于某值的数据_Pandas 数据处理(二) - 筛选数据

Pandas 数据处理(二) - 筛选数据

使用demo.csv举几个栗子~

1

2

3

4

5

6编号,日期,单价,数量

T001,-03-02 12:34:05,100,3

T002,-03-02 13:04:05,200,3

T003,-03-03 18:12:31,30,10

T004,-03-04 20:34:05,400,2

T005,-03-02 20:34:05,500,1

1

2

3

4

5

6

7

8

9

10

11

12import pandas as pd

df = pd.read_csv('demo.csv', index_col='编号') # 指定行标签 label

"""

日期 单价

编号

T001 -03-02 12:34:05 100

T002 -03-02 13:04:05 200

T003 -03-03 18:12:31 30

T004 -03-04 20:34:05 400

T005 -03-02 20:34:05 500

"""

如果不指定 index_col,则会默认生成 0 - 5的行标签,这种情况下,行标签与行号相等。

行标签可以理解为这一行的区别于其他行的标志(类似SQL中的主键)

1

2

3

4

5

6

7

8

9df_without_index_col = pd.read_csv('demo.csv')

"""

编号 日期 单价 数量

0 T001 -03-02 12:34:05 100 3

1 T002 -03-02 13:04:05 200 3

2 T003 -03-03 18:12:31 30 10

3 T004 -03-04 20:34:05 400 2

4 T005 -03-02 20:34:05 500 1

"""

一、选取列

1. 使用方括号1

2

3

4

5

6

7

8

9

10df[['日期', '单价']]

"""

日期 单价

编号

T001 -03-02 12:34:05 100

T002 -03-02 13:04:05 200

T003 -03-03 18:12:31 30

T004 -03-04 20:34:05 400

T005 -03-02 20:34:05 500

"""

1

2

3

4

5

6

7

8

9

10

11df[['单价']] # -> DataFrame

"""

单价

编号

T001 100

T002 200

T003 30

T004 400

T005 500

"""

type(df[['单价']]) #

1

2

3

4

5

6

7

8

9

10

11df['单价'] # -> Series

"""

编号

T001 100

T002 200

T003 30

T004 400

T005 500

Name: 单价, dtype: int64

"""

type(df['单价']) #

二、选取行

1. 行标签使用loc

可接受2个参数,第一个参数是行标签,第二个参数是列标签

行标签为T002的行

1

2

3

4

5

6

7df.loc['T002'] # -> Series

"""

日期 -03-02 12:34:05

单价 100

数量 3

Name: T001, dtype: object

"""

行标签从T002到 T004的行(与切片不同,这种情况下包含开头也包含结束)

1

2

3

4

5

6

7

8df.loc['T002':'T004'] # -> DataFrame

"""

日期 单价 数量

编号

T002 -03-02 13:04:05 200 3

T003 -03-03 18:12:31 30 10

T004 -03-04 20:34:05 400 2

"""

行标签从T002到最后的行,且只选取单价和数量2列

1

2

3

4

5

6

7

8

9

10df.loc['T002':, ['单价', '数量']] # -> DataFrame

# 等价于 df.loc['T002':][['单价', '数量']]

"""

单价 数量

编号

T002 200 3

T003 30 10

T004 400 2

T005 500 1

"""

2. 行号使用iloc第1行到倒数第2行

iloc参数是一个slice对象,和python中可迭代对象用法是一致的。[start, end, step)。

下标从0开始,包含开头,不包含结束。

1

2

3

4

5

6

7df.iloc[1:-2] # -> DataFrame,不包含 -2 行

"""

日期 单价 数量

编号

T002 -03-02 13:04:05 200 3

T003 -03-03 18:12:31 30 10

"""

第1行到最后,隔行取,即行号为单数的行,1,3,5,7,9….

1

2

3

4

5

6

7

8df.iloc[1::2] # -> DataFrame,到最后,切片的第二个参数可省略不写

"""

日期 单价 数量

编号

T002 -03-02 13:04:05 200 3

T004 -03-04 20:34:05 400 2

"""

第0行到第3行,第1列到第3列

1

2

3

4

5

6

7

8df.iloc[:3, 1:3] # -> DataFrame, 等价于 df.iloc[0:3, 1:3],0可以省略不写

"""

单价 数量

编号

T001 100 3

T002 200 3

T003 30 10

"""

若没有指定标签列(index_col),则loc与iloc表现相近

1

2

3

4

5

6

7

8

9

10

11

12

13df_without_index_col.loc[1:3] # 行标签从1到3的行,行标签是包含结束的。

"""

编号 日期 单价 数量

1 T002 -03-02 13:04:05 200 3

2 T003 -03-03 18:12:31 30 10

3 T004 -03-04 20:34:05 400 2

"""

df_without_index_col.iloc[1:3] # 切片是不包含结束的。

"""

编号 日期 单价 数量

1 T002 -03-02 13:04:05 200 3

2 T003 -03-03 18:12:31 30 10

"""

3. ix兼容处理loc与iloc(deprecated)

loc是根据行标签定位的,iloc是根据行号定位的。

ix的处理逻辑是,通常将传入的参数优先视为行标签,若找不到该标签的情况下,再当做行号取索引。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22df.ix['T002':'T004'] # 匹配到了行标签,所以和loc表现一致

"""

日期 单价 数量

编号

T002 -03-02 13:04:05 200 3

T003 -03-03 18:12:31 30 10

T004 -03-04 20:34:05 400 2

"""

df.ix[1:3] # 没有匹配到行标签,所以和iloc一致

"""

日期 单价 数量

编号

T002 -03-02 13:04:05 200 3

T003 -03-03 18:12:31 30 10

"""

df_without_index_col.ix[1:3] # 匹配到了行标签 1,2,3,表现与iloc一致

"""

编号 日期 单价 数量

1 T002 -03-02 13:04:05 200 3

2 T003 -03-03 18:12:31 30 10

3 T004 -03-04 20:34:05 400 2

"""

ix方法虽然兼容处理了2种情况,但是建议不要使用,尽量使用loc和iloc明确索引方式。

当前ix方法已经处于 deprecated 状态。

三、简单条件

1. 简单的逻辑判断(, ==, &, |, ~ 等)单价不小于200的记录

1

2

3

4

5

6

7

8

9df[df['单价'] >= 200]

# 等价于 df[~(df['单价'] < 200)]

"""

日期 单价 数量

编号

T002 -03-02 13:04:05 200 3

T004 -03-04 20:34:05 400 2

T005 -03-02 20:34:05 500 1

"""

单价大于等于200且数量大于1的记录(&表示与,|表示或,~表示非)

1

2

3

4

5

6

7df[(df['单价'] >= 200) & (df['数量'] >= 2)]

"""

日期 单价 数量

编号

T002 -03-02 13:04:05 200 3

T004 -03-04 20:34:05 400 2

"""

四、自定义函数

1. loc

loc函数支持传入自定义的函数进行筛选

筛选总价大于500的记录

1

2

3

4

5

6

7

8

9

10

11

12df.loc[lambda x: x['单价'] * x['数量'] > 500] # 函数入参 x 是整个 DataFrame

"""

日期 单价 数量

编号

T002 -03-02 13:04:05 200 3

T004 -03-04 20:34:05 400 2

"""

# 等价于

def filter_func(x):

print(type(x)) #

return x['单价'] * x['数量'] > 500

df.loc[filter_func]

筛选3月2号的记录

1

2

3

4

5

6

7

8

9# x是整个DataFrame,x['日期']是包含所有记录的Series

df.loc[lambda x: x['日期'].str.startswith('-03-02')]

"""

日期 单价 数量

编号

T001 -03-02 12:34:05 100 3

T002 -03-02 13:04:05 200 3

T005 -03-02 20:34:05 500 1

"""

Series.str(),可以使用Python自带的string相关的方法,构造筛选条件。

2. apply筛选总价大于500的记录

1

2

3

4

5

6

7

8

9

10

11

12df[df.apply(lambda x: x['单价'] * x['数量'] > 500, axis=1)] # 函数入参 x 是一行数据 Series

"""

日期 单价 数量

编号

T002 -03-02 13:04:05 200 3

T004 -03-04 20:34:05 400 2

"""

# 等价于

def filter_func(x):

print(type(x)) #

return x['单价'] * x['数量'] > 500

df[df.apply(filter_func, axis=1)]

axis默认为0,表示遍历列,axis=1,表示遍历行。

筛选3月2号的记录

1

2

3

4

5

6

7

8

9

10df['日期'] = pd.to_datetime(df['日期'])

# x表示一行记录(Series),x['日期']已经是一个具体的日期对象

df[df.apply(lambda x: x['日期'].date() == pd.to_datetime('/03/02').date(), axis=1)]

"""

日期 单价 数量

编号

T001 -03-02 12:34:05 100 3

T002 -03-02 13:04:05 200 3

T005 -03-02 20:34:05 500 1

"""

假如数据中单价包含非数字,需要删除

1

2

3

4

5

6

7编号,日期,单价,数量

T001,-03-02 12:34:05,100,3

T002,-03-02 13:04:05,200,3

T003,-03-03 18:12:31,30,10

T004,-03-04 20:34:05,400,2

T005,-03-02 20:34:05,500,1

T006,-03-02 20:34:05,$#500,1

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19def filter_func(x):

try:

float(x['单价']) # x是为某一行的数据,x['单价']可以取到该行对应的值

return True

except:

return False

df = pd.read_csv('demo.csv', index_col='编号')

print(df[df.apply(filter_func, axis=1)])

"""

日期 单价 数量

编号

T001 -03-02 12:34:05 100 3

T002 -03-02 13:04:05 200 3

T003 -03-03 18:12:31 30 10

T004 -03-04 20:34:05 400 2

T005 -03-02 20:34:05 500.0 1

"""

附 推荐

本文发表于 -03-21,最后修改于 -12-22。

本站永久域名「 极客兔兔 」找到我。

欢迎关注我的

「 知乎 」

和 「 微博 」

,或通过「 RSS 」订阅本站。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。