于贵洋的博客

BI、数据分析


  • 首页

  • 分类

  • 标签

  • 归档

  • 站点地图

  • 公益404

  • 关于

  • 搜索

Pandas手册(7)- pandas数据加载

发表于 2017-08-08 | 分类于 Python-Pandas

Python
Pandas


这里整理下,pandas中数据加载的几个方法,前面,我们也有用过,read_csv,下面,我们整理下

1.pandas读取数据方法

1
pandas.read_csv(filepath_or_buffer, sep=', ', delimiter=None, header='infer', names=None, index_col=None, usecols=None, squeeze=False, prefix=None, mangle_dupe_cols=True, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skipinitialspace=False, skiprows=None, nrows=None, na_values=None, keep_default_na=True, na_filter=True, verbose=False, skip_blank_lines=True, parse_dates=False, infer_datetime_format=False, keep_date_col=False, date_parser=None, dayfirst=False, iterator=False, chunksize=None, compression='infer', thousands=None, decimal=b'.', lineterminator=None, quotechar='"', quoting=0, escapechar=None, comment=None, encoding=None, dialect=None, tupleize_cols=False, error_bad_lines=True, warn_bad_lines=True, skipfooter=0, skip_footer=0, doublequote=True, delim_whitespace=False, as_recarray=False, compact_ints=False, use_unsigned=False, low_memory=True, buffer_lines=None, memory_map=False, float_precision=None)

我们可以看到这个参数非常多,基本上可以解决我们文件读取时的常见问题。

下面就是小例子
csv文件内容是这样的:数据以逗号分隔,没有其他特殊的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import pandas as pd
df = pd.read_csv(r'D:\document\python_demo\pydata-book-master\ch06\ex1.csv')
#使用read_table需要,手动指定下分隔符
#df = pd.read_table(r'D:\document\python_demo\pydata-book-master\ch06\ex1.csv',sep=',')
print(df)
print(df.index)
print(df.columns)
runfile('D:/document/python_demo/pandas_csv.py', wdir='D:/document/python_demo')
a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
RangeIndex(start=0, stop=3, step=1)
Index(['a', 'b', 'c', 'd', 'message'], dtype='object')

我们可以看到,这里默认把第一行当做columns了,我们可以通过header=None,来自动指定标题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
df = pd.read_csv(r'D:\document\python_demo\pydata-book-master\ch06\ex1.csv',header=None)
0 1 2 3 4
0 a b c d message
1 1 2 3 4 hello
2 5 6 7 8 world
3 9 10 11 12 foo
RangeIndex(start=0, stop=4, step=1)
Int64Index([0, 1, 2, 3, 4], dtype='int64')
#通过names,来自定义columns
df = pd.read_csv(r'D:\document\python_demo\pydata-book-master\ch06\ex1.csv',header=None,names=list('opqrxy'))
o p q r x y
0 a b c d message NaN
1 1 2 3 4 hello NaN
2 5 6 7 8 world NaN
3 9 10 11 12 foo NaN
RangeIndex(start=0, stop=4, step=1)
Index(['o', 'p', 'q', 'r', 'x', 'y'], dtype='object')

现在的行索引是自动初始化的,我们可以指定存在的列为索引

1
2
3
4
5
6
7
8
9
10
11
12
13
path = r'D:\document\python_demo\pydata-book-master\ch06\ex1.csv'
df = pd.read_csv(path,header=None,
names=list('opqrxy'),
index_col='x')
o p q r y
x
message a b c d NaN
hello 1 2 3 4 NaN
world 5 6 7 8 NaN
foo 9 10 11 12 NaN
Index(['message', 'hello', 'world', 'foo'], dtype='object', name='x')
Index(['o', 'p', 'q', 'r', 'y'], dtype='object')

比如,有这样一份数据,字段间是通过一个或多个空格来分隔的

我们直接使用read_csv去读取,会发现,列索引有些不友好,我们可以使用正则表达式去分隔

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
df = pd.read_csv(path)
A B C
0 aaa -0.264438 -1.026059 -0.619500
1 bbb 0.927272 0.302904 -0.032399
2 ccc -0.264273 -0.386314 -0.217601
3 ddd -0.871858 -0.348382 1.100491
RangeIndex(start=0, stop=4, step=1)
Index([' A B C'], dtype='object')
#\s表示空格,+表示1个或多个,就是说分隔符是1个或多个空格
df = pd.read_table(path,sep='\s+')
A B C
aaa -0.264438 -1.026059 -0.619500
bbb 0.927272 0.302904 -0.032399
ccc -0.264273 -0.386314 -0.217601
ddd -0.871858 -0.348382 1.100491
Index(['aaa', 'bbb', 'ccc', 'ddd'], dtype='object')
Index(['A', 'B', 'C'], dtype='object')

还有很多其他常用的参数,比如skiprows,可以跳过指定行
下面,再说个填充缺失值的方法,na_values可以将其他我们指定的值也当成NaN处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
na_values : scalar, str, list-like, or dict, default None
Additional strings to recognize as NA/NaN. If dict passed, specific per-column NA values. By default the following values are interpreted as NaN: ‘’, ‘#N/A’, ‘#N/A N/A’, ‘#NA’, ‘-1.#IND’, ‘-1.#QNAN’, ‘-NaN’, ‘-nan’, ‘1.#IND’, ‘1.#QNAN’, ‘N/A’, ‘NA’, ‘NULL’, ‘NaN’, ‘nan’`.
#原始数据是这样的,
something a b c d message
0 one 1 2 3.0 4 NaN
1 two 5 6 NaN 8 world
2 three 9 10 11.0 12 foo
#这里,我们将1,2,4也当成NaN值处理
df = pd.read_csv(path,na_values=[1,2,4])
#加载后,数据就会变成这样
something a b c d message
0 one NaN NaN 3.0 NaN NaN
1 two 5.0 6.0 NaN 8.0 world
2 three 9.0 10.0 11.0 12.0 foo
#我们还可以用一个dict来对不同的列指定NaN值
df = pd.read_csv(path,na_values={'something':['one','three'],'d':[8,12]})
something a b c d message
0 NaN 1 2 3.0 4.0 NaN
1 two 5 6 NaN NaN world
2 NaN 9 10 11.0 NaN foo

#2.pandas导出数据
我们使用read_csv读取数据,处理完之后,我们可能还需要将数据存储起来,还有一个to_csv的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
DataFrame.to_csv(path_or_buf=None, sep=', ', na_rep='', float_format=None, columns=None, header=True, index=True, index_label=None, mode='w', encoding=None, compression=None, quoting=None, quotechar='"', line_terminator='\n', chunksize=None, tupleize_cols=False, date_format=None, doublequote=True, escapechar=None, decimal='.')
##我们就使用这份数据,先读取后,再保存
something,a,b,c,d,message
one,1,2,3,4,NA
two,5,6,,8,world
three,9,10,11,12,foo
df.to_csv(sys.stdout,sep='^')
^something^a^b^c^d^message
0^one^1^2^3.0^4^
1^two^5^6^^8^world
2^three^9^10^11.0^12^foo
#我们看到这个输出,发现,NaN值,导出时,转为了空字符串,这里呢,我们可以手工指定
na_rep : string, default ‘’
df.to_csv(sys.stdout,sep='^',na_rep='NaN')
^something^a^b^c^d^message
0^one^1^2^3.0^4^NaN
1^two^5^6^NaN^8^world
2^three^9^10^11.0^12^foo
#有时候,行列标签可能也不需要,我们也可以禁用
df.to_csv(sys.stdout,sep='^',na_rep='NaN',index=False,header=False)
one^1^2^3.0^4^NaN
two^5^6^NaN^8^world
three^9^10^11.0^12^foo

#3.附录
pandas中还有其他的加载数据方式,像读取HTML,JSON,xml等等,常用的可能还是和数据库取连接,这块后面会再补充,这里就先到这里。

numpy手册(3)-Datetimes and Timedeltas

发表于 2017-08-07 | 分类于 Python-Numpy

Python
Numpy知识总结


这里说下numpy中日期、时间相关的使用。
主要参考:
https://docs.scipy.org/doc/numpy-dev/reference/arrays.datetime.html

基本使用

在numpy中,我们很方便的讲字符串转换成日期类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import numpy as np
np.datetime64('2017-08-06')
Out[3]: numpy.datetime64('2017-08-06')
np.datetime64('2017-08')
Out[4]: numpy.datetime64('2017-08')
#我们可以通过参数,强制将数据格式化为我们想要的粒度
np.datetime64('2017-08' , 'D')
Out[5]: numpy.datetime64('2017-08-01')
np.datetime64('2017-08' , 'Y')
Out[6]: numpy.datetime64('2017')
a = np.array(['2017-07-01','2017-07-15','2017-08-01'] , dtype=np.datetime64)
a
Out[10]: array(['2017-07-01', '2017-07-15', '2017-08-01'], dtype='datetime64[D]')
#我们也可以使用arange函数初始化数组
b = np.arange('2017-08-01','2017-09-01',dtype=np.datetime64)
b
Out[12]:
array(['2017-08-01', '2017-08-02', '2017-08-03', ..., '2017-08-29',
'2017-08-30', '2017-08-31'], dtype='datetime64[D]')

阅读全文 »

Python基础(7)- Selenium使用

发表于 2017-08-07 | 分类于 Python-基础

以前搞Java的时候,知道Selenium是做自动化测试的,后来发现搞爬虫也会用到Selenium,这里就和Python整合方面,简单学习下。

1. 什么是Selenium

Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。–百度百科

官网地址:http://www.seleniumhq.org/
因为Selenium可以录制不同的动作,模拟操作,和Python结合以后,在爬取数据的时候就很方便,所以下面我们来看看需要怎样配置。

#2. 安装配置

2.1火狐浏览器插件安装

插件地址:https://addons.mozilla.org/en-US/firefox/addon/selenium-ide/

安装之后,我们可以直接在浏览器中使用Selenium

2.2火狐浏览器driver下载

这个再后面会用到,地址:https://github.com/mozilla/geckodriver/releases
WebDriver是Selenium的API,我们用Python集成开发会很方便,这个下载后,需要放到Path路径下

image.pngimage.png

2.3Python安装Selenium模块

1
pip install selenium

3.示例代码

我们先来看一个简单的例子,我们打开火狐浏览器,然后让浏览器加载一个URL

1
2
3
4
5
6
7
8
9
10
11
12
from selenium import webdriver
browser = webdriver.Firefox()
browser.get('http://www.baidu.com/')
error 信息:
File "D:\Users\yugui\Anaconda3\lib\site-packages\selenium\webdriver\common\service.py", line 81, in start
os.path.basename(self.path), self.start_error_message)
WebDriverException: 'geckodriver' executable needs to be in PATH.

刚开始可能会报错,这是因为我们上面的那个driver没有加到PATH。
加到PATH后,再次执行,就可打开浏览器了

再来看一个略复杂的例子:
这是官方中的例子:http://www.seleniumhq.org/docs/03_webdriver.jsp#selenium-webdriver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0
#1.打开浏览器
browser = webdriver.Firefox()
#2.浏览器加载地址
browser.get('https://www.baidu.com/')
#3.输出浏览器标题
print(browser.title)
#4.一个断言,浏览器标题中包含'百度'关键字
assert '百度' in browser.title
#5.根据ID,获取搜索框
elem = browser.find_element_by_id('kw')
#模拟输入Python,进行搜索
elem.send_keys('python')
elem.submit()
try:
# 等待浏览器刷新,返回我们的搜索结果
WebDriverWait(browser, 10).until(EC.title_contains("python"))
# 输出当前浏览器的标题
print(browser.title)
finally:
# 关闭浏览器
browser.quit()

执行后,我们会看到,打开浏览器,然后搜索‘Python’,返回搜索结果后会关闭。

4.获取控件的方式

在上面的例子中,我们使用了find_element_by_id,就是通过标签的id来获取元素
这个和JS里面的差不多,还有很多其他的方法

1
2
3
4
5
6
7
8
9
10
11
#by id
#<div id="coolestWidgetEvah">...</div>
find_element_by_id(id_)
element = driver.find_element_by_id("coolestWidgetEvah")
#by class name
#<div class="cheese"><span>Cheddar</span></div><div class="cheese"><span>Gouda</span></div>
find_element_by_class_name(name)
cheeses = driver.find_elements_by_class_name("cheese")

论坛里这篇博客写的很好:Python3中Selenium使用方法

5. 实例练习

这里顺便写个小例子,练习下,我们方位豆瓣读书,然后搜索关键字,将所有的书都打印出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException
#打开浏览器
browser = webdriver.Firefox()
#设置等待时长,最长等待10s
wait = WebDriverWait(browser,10)
#打开URL
browser.get('https://book.douban.com/')
#输出浏览器标题
print('browser title: ',browser.title)
#获取搜索框
inp_query = wait.until(EC.presence_of_element_located((By.ID,'inp-query')))
inp_query.send_keys('onepiece')
#可以直接提交,或者获取提交按钮再提交
inp_query.submit()
'''
#获取提交按钮
inp_btn = browser.find_element_by_class_name('inp-btn').find_element_by_tag_name('input')
inp_btn.click()
'''
def show_current_page():
print('-----------------------------------')
print('current url: ',browser.current_url)
#<ul class="subject-list">
rs = wait.until(EC.presence_of_element_located((By.CLASS_NAME,'subject-list')))
book_list = rs.find_elements_by_tag_name('li')
print('current page total book: ',len(book_list))
print('info:',browser.find_element_by_class_name('trr').text)
#输出书的名字
for book in book_list:
print(book.find_element_by_tag_name('h2').text)
print('-----------------------------------')
#进入下一页
show_next_page()
def show_next_page():
#获取下一页的标签
#<span class="next">
span_next = wait.until(EC.presence_of_element_located((By.CLASS_NAME,'next')))
try:
#获取span中的a标签
a_next = span_next.find_element_by_tag_name('a')
a_next.click()
show_current_page()
except NoSuchElementException:
#已经没有下一页,可以退出了
print('now print all pages.')
finally:
browser.quit()
show_current_page()
#time.sleep(10)
#退出
browser.quit()

这里的元素获取方式,不是最佳的,代码还得继续优化,这个下一页挺好玩儿的,

刚刚简单优化了下代码,主要改了些元素选择的方式,更直接了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
#打开浏览器
browser = webdriver.Firefox()
#设置等待时长,最长等待10s
wait = WebDriverWait(browser,10)
def main():
#打开URL
browser.get('https://book.douban.com/')
#输出浏览器标题
print('browser title: ',browser.title)
#获取搜索框
inp_query = wait.until(EC.presence_of_element_located((By.ID,'inp-query')))
inp_query.send_keys('onepiece')
#可以直接提交,或者获取提交按钮再提交
inp_query.submit()
show_current_page()
def show_current_page():
print('-----------------------------------')
print('current url: ',browser.current_url)
#搜索结果-汇总信息
page_info = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'div.article div.trr')))
print('info: ',page_info.text)
#搜索结果-书籍列表
book_list = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,'div.article ul.subject-list li.subject-item')))
print('current page total book: ',len(book_list))
for book in book_list:
print(book.find_element_by_tag_name('h2').text)
print('-----------------------------------')
#进入下一页
show_next_page()
def show_next_page():
try:
#获取下一页的标签
a_next = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'div.article div.paginator span.next a')))
a_next.click()
show_current_page()
except TimeoutException:
print('超时了.')
span_next = EC.invisibility_of_element_located((By.CSS_SELECTOR,'div.article div.paginator span.next'))
if span_next:
print('now print all pages.')
else :
#真的超时,重试一次
show_next_page()
finally:
browser.quit()
if __name__=='__main__':
main()

Pandas手册(6)- 用pandas完成excel中常见任务

发表于 2017-08-07 | 分类于 Python-Pandas

Python
Pandas


这里整理下pandas常用的操作,为什么要写这个呢?有本书《利用Python进行数据分析》一边看一遍记录下。

1. 重新索引(reindex)

就是重构一下索引,在重构的同时,我们可以做一些其他操作

1
2
3
4
5
DataFrame.reindex(index=None, columns=None, **kwargs)
Conform DataFrame to new index with optional filling logic, placing NA/NaN in locations having no value in the previous index. A new object is produced unless the new index is equivalent to the current one and copy=False
Series.reindex(index=None, **kwargs)
Conform Series to new index with optional filling logic, placing NA/NaN in locations having no value in the previous index. A new object is produced unless the new index is equivalent to the current one and copy=False

一个小例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
obj
Out[156]:
d 4.5
b 7.2
a -5.3
c 3.6
dtype: float64
#reindex后,没有的值,默认会用NaN填充
obj.reindex(['a','b','c','d','e'])
Out[157]:
a -5.3
b 7.2
c 3.6
d 4.5
e NaN
dtype: float64
#fill_value,常用的参数,表示没有数据时默认填充的值
obj.reindex(['a','b','c','d','e'] , fill_value=9.9)
Out[159]:
a -5.3
b 7.2
c 3.6
d 4.5
e 9.9
dtype: float64
#method,常用参数,在递增或递减index中,填充空值的方法
obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
obj3
Out[165]:
0 blue
2 purple
4 yellow
dtype: object
obj3.reindex(range(6))
Out[170]:
0 blue
1 NaN
2 purple
3 NaN
4 yellow
5 NaN
dtype: object
#ffill,前向填充
obj3.reindex(range(6),method='ffill')
Out[167]:
0 blue
1 blue
2 purple
3 purple
4 yellow
5 yellow
dtype: object
#bfill,后向填充
obj3.reindex(range(6),method='bfill')
Out[171]:
0 blue
1 purple
2 purple
3 yellow
4 yellow
5 NaN
dtype: object

对于DataFrame来说,用起来也是差不多的

2. 丢弃指定轴上的项

主要就是drop方法的使用

1
2
DataFrame.drop(labels, axis=0, level=None, inplace=False, errors='raise')
Return new object with labels in requested axis removed.

小例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
obj = pd.Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
obj
Out[174]:
a 0.0
b 1.0
c 2.0
d 3.0
e 4.0
dtype: float64
obj.drop('c')
Out[175]:
a 0.0
b 1.0
d 3.0
e 4.0
dtype: float64
obj.drop(['b','d'])
Out[176]:
a 0.0
c 2.0
e 4.0
dtype: float64
#DataFrame
data = pd.DataFrame(np.arange(16).reshape((4, 4)),
index=['Ohio', 'Colorado', 'Utah', 'New York'],
columns=['one', 'two', 'three', 'four'])
data
Out[178]:
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
#默认是横轴,
data.drop(['Ohio','Utah'])
Out[179]:
one two three four
Colorado 4 5 6 7
New York 12 13 14 15
#我们可以指定axis,在columns上删除
data.drop(['two','four'],axis=1)
Out[180]:
one three
Ohio 0 2
Colorado 4 6
Utah 8 10
New York 12 14

3. 算术运算和数据对齐

在numpy和pandas中好像都会看到这个词,数据对齐,就是说2个对象在运算的时候,会取一个并集,然后在自动对齐的时候,不重叠的部分就会填充NaN

小例子先看看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
s1 = pd.Series([7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'])
s2 = pd.Series([-2.1, 3.6, -1.5, 4, 3.1], index=['a', 'c', 'e', 'f', 'g'])
#index不重叠的地方,会填充NaN
s1+s2
Out[188]:
a 5.2
c 1.1
d NaN
e 0.0
f NaN
g NaN
dtype: float64
#使用自带的add方法,就可以填充默认值了,这个和我们上面reindex时的思想是一样的
#Series.add(other, level=None, fill_value=None, axis=0)
s1.add(s2,fill_value=0)
Out[189]:
a 5.2
c 1.1
d 3.4
e 0.0
f 4.0
g 3.1
dtype: float64

4.DataFrame和Series之间的运算

这里用到了一个广播的思想,就是指不同形状的数组之间的算术运算的执行方式,很强大的功能,这里,我们先简单了解下。
小例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
arr = np.arange(12.).reshape((3, 4))
arr
Out[191]:
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])
arr[0]
Out[192]: array([ 0., 1., 2., 3.])
#3行4列的数组,减1行4列的数组,这就是广播
arr - arr[0]
Out[193]:
array([[ 0., 0., 0., 0.],
[ 4., 4., 4., 4.],
[ 8., 8., 8., 8.]])

DataFrame和Series之间的计算也是这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
frame = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'),
index=['Utah', 'Ohio', 'Texas', 'Oregon'])
frame
Out[195]:
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
s = frame.iloc[0]
s
Out[197]:
b 0.0
d 1.0
e 2.0
Name: Utah, dtype: float64
frame - s
Out[198]:
b d e
Utah 0.0 0.0 0.0
Ohio 3.0 3.0 3.0
Texas 6.0 6.0 6.0
Oregon 9.0 9.0 9.0
s = pd.Series(range(3),index=list('abc'))
frame
Out[223]:
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
s
Out[224]:
a 0
b 1
c 2
dtype: int32
frame.add(s)
Out[225]:
a b c d e
Utah NaN 1.0 NaN NaN NaN
Ohio NaN 4.0 NaN NaN NaN
Texas NaN 7.0 NaN NaN NaN
Oregon NaN 10.0 NaN NaN NaN
#我们可以通过axis控制在哪个方向上去广播
frame.add(s,axis=0)
Out[227]:
b d e
Ohio NaN NaN NaN
Oregon NaN NaN NaN
Texas NaN NaN NaN
Utah NaN NaN NaN
a NaN NaN NaN
b NaN NaN NaN
c NaN NaN NaN

在这里,不能使用fill_value填充默认值,还不知道为啥,总是报错,说不支持

5. 函数应用和映射

这里主要是介绍DataFrame中的一个函数使用,apply,就是对DataFrame中的每一个元素执行传入的函数

1
2
DataFrame.apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds)
Applies function along input axis of DataFrame.

小例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
f = lambda x: x+10
#每一个单元格都会加10
frame.apply(f)
Out[230]:
b d e
Utah 10.0 11.0 12.0
Ohio 13.0 14.0 15.0
Texas 16.0 17.0 18.0
Oregon 19.0 20.0 21.0
f = lambda x: x.max() - x.min()
frame.apply(f)
Out[232]:
b 9.0
d 9.0
e 9.0
dtype: float64
#我们可以指定轴,去执行函数
frame.apply(f,axis=1)
Out[233]:
Utah 2.0
Ohio 2.0
Texas 2.0
Oregon 2.0
dtype: float64

这里还有一个applymap函数

1
2
3
DataFrame.applymap(func)
Apply a function to a DataFrame that is intended to operate elementwise, i.e. like doing map(func, series) for each series in the DataFrame

这里得注意下,这2个函数的区别;
目前的理解是,applymap是元素级的,apply在轴上进行操作(貌似不太顺,等明白了再记录下)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
f = lambda x: '${:,.3f}'.format(x)
frame
Out[237]:
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
#前面,我们有用过,格式化内容的
frame.applymap(f)
Out[238]:
b d e
Utah $0.000 $1.000 $2.000
Ohio $3.000 $4.000 $5.000
Texas $6.000 $7.000 $8.000
Oregon $9.000 $10.000 $11.000

6.处理缺失数据

在pandas中处理缺失数据非常容易,pandas使用浮点值NaN(Not a Number)表示缺失值。
前面,我们说过使用isnull来判断是否有NaN值
小例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
a = pd.Series(['one','two',np.nan,'three'])
a
Out[240]:
0 one
1 two
2 NaN
3 three
dtype: object
a.isnull()
Out[241]:
0 False
1 False
2 True
3 False
dtype: bool
a.notnull()
Out[242]:
0 True
1 True
2 False
3 True
dtype: bool
#Python内置的None也会被当做NaN处理
a[4]=None
a
Out[247]:
0 one
1 two
2 NaN
3 three
4 None
dtype: object
a.isnull()
Out[248]:
0 False
1 False
2 True
3 False
4 True
dtype: bool

对于这种数据,我们要怎样处理呢?有的时候,我们可能会初始化为默认值,或者直接剔除掉
我们可以使用dropna函数来剔除掉,或者布尔类型索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
a
Out[249]:
0 one
1 two
2 NaN
3 three
4 None
dtype: object
a.dropna()
Out[250]:
0 one
1 two
3 three
dtype: object
a[a.notnull()]
Out[251]:
0 one
1 two
3 three
dtype: object
##dataframe
data = pd.DataFrame([[1., 6.5, 3.], [1., np.nan, np.nan],
[np.nan, np.nan, np.nan], [np.nan, 6.5, 3.]])
data
Out[254]:
0 1 2
0 1.0 6.5 3.0
1 1.0 NaN NaN
2 NaN NaN NaN
3 NaN 6.5 3.0
#默认的话,会将行、列含有NaN的都剔除掉
data.dropna()
Out[255]:
0 1 2
0 1.0 6.5 3.0
#我们可以使用参数how来控制
how : {‘any’, ‘all’}
any : if any NA values are present, drop that label
all : if all values are NA, drop that label
data.dropna(how='all')
Out[257]:
0 1 2
0 1.0 6.5 3.0
1 1.0 NaN NaN
3 NaN 6.5 3.0

有的时候,我们想要做填充而不是剔除,像我们前面使用的参数fill_value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)
Fill NA/NaN values using the specified method
method : {‘backfill’, ‘bfill’, ‘pad’, ‘ffill’, None}, default None
data
Out[261]:
0 1 2
0 1.0 6.5 3.0
1 1.0 NaN NaN
2 NaN NaN NaN
3 NaN 6.5 3.0
data.fillna(9.9)
Out[259]:
0 1 2
0 1.0 6.5 3.0
1 1.0 9.9 9.9
2 9.9 9.9 9.9
3 9.9 6.5 3.0
#使用method,和前面reindex的时候是一个道理
data.fillna(method='ffill')
Out[262]:
0 1 2
0 1.0 6.5 3.0
1 1.0 6.5 3.0
2 1.0 6.5 3.0
3 1.0 6.5 3.0

Python基础(6)- zip

发表于 2017-08-06 | 分类于 Python-基础

这里记录一个函数的使用,zip

1
2
3
4
5
6
zip(iter1 [,iter2 [...]]) --> zip object
Return a zip object whose .__next__() method returns a tuple where
the i-th element comes from the i-th iterable argument. The .__next__()
method continues until the shortest iterable in the argument sequence
is exhausted and then it raises StopIteration.

我们可以传入一个或多个可迭代对象,然后将对应位置的元素封装成一个tuple,然后把所有tuple封装为list返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
x = [1,2,3]
y = [4,5,6]
z = zip(x,y)
print(z)
<zip object at 0x000002D26251F208>
print(list(z))
[(1, 4), (2, 5), (3, 6)]
#在只有一个参数的时候
a = zip(x)
a
Out[8]: <zip at 0x2d261cab588>
list(a)
Out[9]: [(1,), (2,), (3,)]

如果2个参数的长度不一样,会以较短的为主

1
2
3
4
5
6
7
8
a = [1,2,3]
b = ['ONE', 'TWO', 'THREE', 'FOUR']
c = list(zip(a,b))
c
Out[31]: [(1, 'ONE'), (2, 'TWO'), (3, 'THREE')]

我们使用*,可以看做是unzip的过程

1
2
3
4
5
6
7
8
x = [1,2,3]
y = [4,5,6]
z = zip(*zip(x,y))
list(z)
Out[27]: [(1, 2, 3), (4, 5, 6)]

关于zip,有几个常用的场景,比如矩阵行列转换

1
2
3
4
5
6
7
a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
list(zip(*a))
Out[38]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
list(map(list,zip(*a)))
Out[39]: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

构造字典

1
2
3
4
5
6
7
8
9
a = [1,2,3]
b = ['one','two','three']
list(zip(a,b))
Out[42]: [(1, 'one'), (2, 'two'), (3, 'three')]
dict(list(zip(a,b)))
Out[43]: {1: 'one', 2: 'two', 3: 'three'}

参考博客:
http://blog.csdn.net/shomy_liu/article/details/46968651
http://www.jb51.net/article/53051.htm

1…141516…23
于贵洋

于贵洋

111 日志
17 分类
30 标签
RSS
GitHub
友情链接
  • 很久之前的CSDN博客
0%
© 2017 于贵洋
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.3
Hosted by GitHub Pages
本站访客数 人次 本站总访问量 次