# -*-coding:utf-8-*-
# ---------------------
# Chapter 1 - Reading from a CSV.ipynb
# ---------------------
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
"""
1.1 Reading data from a csv file
"""
broken_df = pd.read_csv('data/bikes.csv')
# seq为分隔符,encoding为编码,index_col为索引列编号,dayfirst为日期格式,parse_dates为日期解析
fixed_df = pd.read_csv('data/bikes.csv', sep=';', encoding='latin1', parse_dates=['Date'], dayfirst=True,
index_col='Date')
fixed_df[:3]
type(fixed_df) # <class 'pandas.core.frame.DataFrame'>
"""
1.2 Selecting a column
"""
fixed_df['Berri 1']
"""
1.3 Plotting a column
"""
fixed_df['Berri 1'].plot()
plt.show()
fixed_df.plot(figsize=(15, 10))
plt.show()
"""
1.4 Putting all that together
"""
df = pd.read_csv('data/bikes.csv', sep=';', encoding='latin1', parse_dates=['Date'], dayfirst=True, index_col='Date')
df['Berri 1'].plot()
plt.show()
# ---------------------
# Chapter 2 - Selecting data & finding the most common complaint type.ipynb
# ---------------------
pd.set_option('display.line_width', 5000)
pd.set_option('display.max_columns', 60)
complaints = pd.read_csv('data/311-service-requests.csv')
complaints.head()
complaints['Complaint Type']
complaints[:3]
complaints['Complaint Type'][:3]
complaints[:3]['Complaint Type']
complaints[['Complaint Type', 'Borough']]
complaints[['Complaint Type', 'Borough']][:10]
complaints_counts = complaints['Complaint Type'].value_counts() # 计算各个元素的数量
complaints_counts[:10]
complaints_counts[:10].plot(kind='bar')
plt.show()
# ---------------------
# Chapter 3 - Which borough has the most noise complaints (or, more selecting data).ipynb
# ---------------------
complaints = pd.read_csv('data/311-service-requests.csv') # 读取csv文件
complaints.head()
complaints[:5]
'''
3.1 Selecting only noise complaints
'''
noise_complaints = complaints[complaints['Complaint Type'] == 'Noise - Street/Sidewalk']
noise_complaints[:3]
complaints['Complaint Type'] == 'Noise - Street/Sidewalk' # 返回True False
is_noise = complaints['Complaint Type'] == 'Noise - Street/Sidewalk'
in_brooklyn = complaints['Borough'] == 'BROOKLYN'
complaints[is_noise & in_brooklyn][:5]
complaints[is_noise & in_brooklyn][['Complaint Type', 'Borough', 'Created Date', 'Descriptor']][:10]
'''
3.2 A digression about numpy arrays
'''
pf = pd.Series([1, 2, 3])
pf
pf.values
pf.index
nf = np.array([1, 2, 3])
nf
nf != 2
nf[nf != 2]
'''
3.3 So, which borough has the most noise complaints?
'''
is_noise = complaints['Complaint Type'] == "Noise - Street/Sidewalk"
noise_complaints = complaints[is_noise]
noise_complaints['Borough'].value_counts()
noise_complaint_counts = noise_complaints['Borough'].value_counts()
complaint_counts = complaints['Borough'].value_counts()
noise_complaint_counts / complaint_counts
noise_complaint_counts / complaint_counts.astype(float)
(noise_complaint_counts / complaint_counts.astype(float)).plot(kind='bar')
plt.show()
# ---------------------
# Chapter 4: Find out on which weekday people bike the most with groupby and aggregate
# ---------------------
bikes = pd.read_csv('data/bikes.csv', sep=';', encoding='latin1', index_col='Date', parse_dates=['Date'],
dayfirst=True)
bikes.head()
bikes['Berri 1'].plot() # 绘制曲线
plt.show()
berri_bikes = bikes[['Berri 1']].copy() # 将某一列的数据复制出来,单独为一列
berri_bikes[:5]
berri_bikes.index
berri_bikes.index.day
berri_bikes.index.weekday
berri_bikes.loc[:, 'weekday'] = berri_bikes.index.weekday
berri_bikes[:5]
"""
4.2 Adding up the cyclists by weekday
"""
"""
使用DataFrames中的.groupby()方法进行分组,并计算每一组的数量和
"""
weekday_counts = berri_bikes.groupby('weekday').aggregate(sum)
weekday_counts
weekday_counts.index = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
weekday_counts
weekday_counts.plot(kind='bar')
plt.show()
"""
4.3 Putting it together
"""
"""
所有代码汇总
"""
bikes = pd.read_csv('data/bikes.csv', sep=';', encoding='latin1', index_col='Date', dayfirst=True,
parse_dates=['Date'])
berri_bikes = bikes[['Berri 1']].copy()
berri_bikes.loc[:, 'weekday'] = berri_bikes.index.weekday
weekday_counts = berri_bikes.groupby('weekday').aggregate(sum)
weekday_counts.index = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
weekday_counts.plot(kind='bar')
plt.show()
"""
分析:
主要是计算时间,分组处理一周时间,将每周对应的数量加到对应的天上
方法:
1、csv数据的读取
2、列数据的复制
3、将数据按照一周来进行划分
4、按照一周进行分组处理数据,修改索引
5、直方图展示
"""
# ---------------------
# Chapter 5: Combining dataframes and scraping Canadian weather data
# ---------------------
'''
Summary
'''
weather_2012_final = pd.read_csv('data/weather_2012.csv', index_col='Date/Time')
weather_2012_final.head()
weather_2012_final['Temp (C)'].plot(figsize=(15, 6))
plt.show()
'''
5.1 Downloading one month of weather data
'''
url_template = "http://climate.weather.gc.ca/climate_data/bulk_data_e.html?format=csv&stationID=31407&Year={year}&Month={month}&timeframe=1&submit=%E4%B8%8B%E8%BD%BD%E6%95%B0%E6%8D%AE";;
url = url_template.format(month=3, year=2012)
weather_mar2012 = pd.read_csv(url, skiprows=15, index_col='Date/Time', parse_dates=True, encoding='latin1', header=0)
weather_mar2012
weather_mar2012['Temp (°C)'].plot(figsize=(15, 5)) # 图形展示温度变化情况
plt.show()
weather_mar2012.columns = [
u'Year', u'Month', u'Day', u'Time', u'Data Quality', u'Temp (°C)',
u'Temp Flag', u'Dew Point Temp (C)', u'Dew Point Temp Flag',
u'Rel Hum (%)', u'Rel Hum Flag', u'Wind Dir (10s deg)', u'Wind Dir Flag',
u'Wind Spd (km/h)', u'Wind Spd Flag', u'Visibility (km)', u'Visibility Flag',
u'Stn Press (kPa)', u'Stn Press Flag', u'Hmdx', u'Hmdx Flag', u'Wind Chill',
u'Wind Chill Flag', u'Weather']
# weather_mar2012 = weather_mar2012.dropna(axis=1, how='any') # drop the column if any value is null 删除空列
weather_mar2012[:5]
# weather_mar2012 = weather_mar2012.drop(['Year', 'Month', 'Day', 'Time'], axis=1)
weather_mar2012
'''
5.2 Plotting the temperature by hour of day
'''
temperatures = weather_mar2012[['Temp (°C)']].copy()
temperatures.head()
temperatures.loc[:, 'Hour'] = weather_mar2012.index.hour
temperatures.groupby('Hour').aggregate(np.median).plot()
plt.show()
'''
5.3 Getting the whole year of data
'''
def download_weather_month(year, month):
if month == 1:
year += 1
url = url_template.format(year=year, month=month)
weather_data = pd.read_csv(url, skiprows=15, index_col='Date/Time', parse_dates=True, header=True)
weather_data = weather_data.dropna(axis=1)
weather_data.columns = [col.replace('\xb0', '') for col in weather_data.columns]
weather_data = weather_data.drop(['Year', 'Day', 'Month', 'Time', 'Data Quality'], axis=1)
return weather_data
download_weather_month(2012, 1)[:5]
data_by_month = [download_weather_month(2012, i) for i in range(1, 12)] # 所有月份
weather_2012 = pd.concat(data_by_month)
weather_2012
'''
5.4 Saving to a CSV
'''
weather_2012.to_csv('data/weather_2012.csv')
# ---------------------
# Chapter 6 - String Operations- Which month was the snowiest.ipynb
# ---------------------
weather_2012 = pd.read_csv('data/weather_2012.csv', encoding='latin1', index_col='Date/Time', parse_dates=True)
weather_2012.head()
'''
6.1 String operations
'''
weather_description = weather_2012['Weather'] # 取出天气那一列
# 天气是否为snow,若天气为snow,返回True,否则返回False;str将类型转换成字符串形式,利于字符串的匹配、替换和截取
is_snowing = weather_description.str.contains('Snow')
is_snowing = is_snowing.astype(float)
is_snowing.plot() # 将一年中下雪的天全部显示出来
plt.show()
'''
6.2 Use resampling to find the snowiest month 寻找下雪最多的月份
'''
'''
每个月份的平均气温,可以使用resample()方法来实现
'''
weather_2012['Temp (C)'].resample('M', how=np.median).plot(kind='bar') # 平均气温
plt.show()
# 将天气情况使用0和1来表示,若为snow,也就是True,则返回1,否则用0表示
is_snowing.astype(float)[:10] # astype用于类型转换,bool类型转换为float类型
# 使用resample()查找出每个月下雪的可能性,用百分比来表示
is_snowing.astype(float).resample('M', how=np.mean) # 'M':表示按月的时间频率
is_snowing.astype(float).resample('M', how=np.mean).plot(kind='bar')
plt.show()
'''
6.3 Plotting temperature and snowiness stats together 温度和下雪一起分析
'''
temperature = weather_2012['Temp (C)'].resample('M', how=np.median) # 平均温度
is_snowing = weather_2012['Weather'].str.contains('Snow')
snowiness = is_snowing.astype(float).resample('M', how=np.mean) # 下雪比例
temperature.name = 'Temperature'
snowiness.name = 'Snowiness'
stats = pd.concat([temperature, snowiness], axis=1)
stats
stats.plot(kind='bar') # 下雪比例在图示中显示太小,所以这里不合理
plt.show()
stats.plot(kind='bar', subplots=True, figsize=(15, 10)) # 将两张图放到一个平面上,分开放,这样就能合理的进行图像展示
plt.show()
# subplot()作用:将多个figure放到一个平面上
# ---------------------
# Chapter 7 - Cleaning up messy data.ipynb 清理垃圾数据
# ---------------------
requests = pd.read_csv('data/311-service-requests.csv')
# requests.head()
'''
7.1 How do we know if it's messy?
'''
zip = requests['Incident Zip'].unique() # unique()用于查看所有的值
# zip
'''
zip中存在的问题:
1、数据类型问题,有些是字符串型,有些是浮点型
2、有一些值不存在nan
3、有些值不正确 83 29616-0759
4、有N/A值,pandas不能够识别,'N/A','NO CLUE'
处理方法:
1、使'N/A','NO CLUE'变成规则的nan
2、使所有格式都变成字符串
'''
'''
7.3 Fixing the nan values and string/float confusion
'''
na_value = ['N/A', 'NO CLUE', 'O', 'nan']
requests = pd.read_csv('data/311-service-requests.csv', na_values=na_value, dtype={'Incident Zip': str})
# 读取csv文件时,将异常值设置为空值,将数据类型全部转换为字符串类型
zip = requests['Incident Zip'].copy()
# zip.unique()
'''
7.4 What's up with the dashes? 处理数字之间的横杠29616-0759
'''
row_with_dashs = requests['Incident Zip'].str.contains('-').fillna(False) # 将带横杠的全部提取出来
# len(requests[row_with_dashs])
# requests[row_with_dashs]
requests['Incident Zip'][row_with_dashs] = np.nan # 将带横杠的全部转换为空值
# requests['Incident Zip'].unique()
long_zip_codes = requests['Incident Zip'].str.len() > 5
# requests['Incident Zip'][long_zip_codes].unique()
requests['Incident Zip'] = requests['Incident Zip'].str.slice(0, 5) # slice()获取字符串的指定长度
# requests['Incident Zip'] = requests['Incident Zip'].str[0:5]
# requests['Incident Zip'].unique()
# requests[requests['Incident Zip']] == '00000'
zero_zips = requests['Incident Zip'] == '00000'
requests.loc[zero_zips, 'Incident Zip'] = np.nan
unique_zips = requests['Incident Zip'].unique()
unique_zips.sort() # 排序
unique_zips
zips = requests['Incident Zip']
is_close = zips.str.startswith('0') | zips.str.startswith('1') # zip以0或1开头
is_far = ~(is_close) & zips.notnull()
zips[is_far]
requests[is_far][['Incident Zip', 'Descriptor', 'City']].sort('Incident Zip')
requests['City'].str.upper().value_counts() # 城市名转换为大写的,并且统计城市的数量
'''
7.5 Putting it together
'''
# 异常值处理及csv文件的读取
na_values = ['NO CLUE', 'N/A', '0']
requests = pd.read_csv('data/311-service-requests.csv',
na_values=na_values,
dtype={'Incident Zip': str})
# 将邮政编码的位数固定为5位
def fix_zip_codes(zips):
zips = zips.str.slice(0, 5)
zero_zips = zips == '00000'
zips[zero_zips] = np.nan
return zips
requests['Incident Zip'] = fix_zip_codes(requests['Incident Zip'])
requests['Incident Zip'].unique()
# ---------------------
# Chapter 8 - How to deal with timestamps.ipynb
# ---------------------
'''
8.1 Parsing Unix timestamps
'''
popcon = pd.read_csv('data/popularity-contest', sep=' ')
# popcon.head()
popcon.columns = ['atime', 'ctime', 'package-name', 'mru-program', 'tag']
# popcon[:5]
popcon['atime'].dtype
popcon['atime'] = popcon['atime'].astype(int)
# popcon['atime'][:5]
# popcon['ctime'] = popcon['ctime'].astype(int)
popcon['atime'] = pd.to_datetime(popcon['atime'])
# popcon['ctime'] = pd.to_datetime(popcon['ctime'], unit='s')
# popcon['atime'][:5]
popcon = popcon[popcon['atime'] > '1970-01-01']
nonlibraries = popcon[~popcon['package-name'].str.contains('lib')]
nonlibraries.sort('ctime', ascending=False)[:10]
# ---------------------
# Chapter 9 - Loading data from SQL databases.ipynb
# ---------------------
import sqlite3
import pandas as pd
"""
pandas can read from HTML,JSON,SQL,EXCEL,HDF5,Stata, and a few other things.
Read data from a SQL database using the pd.read_sql function.
read_sql take 2 arguments: a SELECT statement, and s database connection object.
This is great because it means you can read from any kind of SQL database,
it doesn't matter if it's MySQL,SQLite,PostgreSQL,or something else.
"""
"""
9.1 Reading data from SQL databases 读取数据
"""
con = sqlite3.connect('../data/weather_2012.sqlite')
df = pd.read_sql('select * from weather_2012 LIMIT 3', con, index_col='id') # 设置id索引
# df
df = pd.read_sql('select * from weather_2012 LIMIT 3', con, index_col=['id', 'date_time']) # 设置双重索引
# df
"""
9.2 Writing to a SQLite database 写入数据
"""
# weather_df = pd.read_csv('../data/weather_2012.csv')
# con = sqlite3.connect('../data/test_db.sqlite')
# con.execute('drop table if exists weather_2012')
# weather_df.to_sql('weather_2012', con)
con = sqlite3.connect('../data/test_db.sqlite')
df = pd.read_sql('select * from weather_2012 LIMIT 3', con, index_col='index')
# df
con = sqlite3.connect('../data/test_db.sqlite')
df = pd.read_sql('select * from weather_2012 order by Weather LIMIT 3', con)
df
"""
sqlite3 database:连接数据库-->sqlite3.connect()
PostgreSQL database:连接数据库-->psycopg2.connect()
MySQL database:连接数据库-->MySQLdb.connect()
"""
"""
9.3 Connecting to other kinds of database
"""
import MySQLdb
con = MySQLdb.connect(host='localhost', db='test')
import psycopg2
con = psycopg2.connect(host='localhost')
Pandas入门
之前由于为了使用,简单的学习下Pandas,而后发现它是个强大的家伙~,因为python版本进行了更新,随之有些api有所改动,所以重新整理官网入门级demo教程来加深印象~
Pandas易于使用的数据结构和数据分析工具。中文称呼为:熊猫!
这是关于pandas的简短介绍,主要面向新用户。可以参阅Cookbook了解更复杂的使用方法。习惯上,我们做以下导入
import pandas as pd
import numpy as np
import matplotlib.pyplot as pl
请参阅数据结构介绍部分
s = pd.Series([1,3,5,np.nan,6,8])
s
dates = pd.date_range('20130101', periods=6)
dates
df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))
df
DataFrame通过传递一个字典,可以转换为一序列对象。
df2 = pd.DataFrame({ 'A' : 1.,
'B' : pd.Timestamp('20130102'),
'C' : pd.Series(1,index=list(range(4)),dtype='float32'),
'D' : np.array([3] * 4,dtype='int32'),
'E' : pd.Categorical(["test","train","test","train"]),
'F' : 'foo' })
df2
明确所有类型
df2.dtype
# 查看框架的顶部和底部的行
df.head()#全部内容
df.tail(3)#底部三行
#显示索引,列和底层numpy数据
df.index #显示索引kye
df.columns# 显示列值*(A,B,C,D)
df.values #只显示值
# 描述显示您的数据的快速统计摘要
df.describe()
#转置您的数据
df.T #x-y颠倒
# 按轴排序
df.sort_index(axis=1, ascending=False)
# 按值排序
df.sort_values(by='B')
注释: 标准Python / Numpy表达式可以完成这些互动工作, 但在生产代码中, 我们推荐使用优化的pandas数据访问方法, .at, .iat, .loc, .iloc 和 .ix.
# 读取
# 选择单列, 这会产生一个序列, 等价df.A
df['A']
# 选择通过[],切行片
df[0:3] #取前面三行
df['20130102':'20130104'] #取包含2013-01-02 到2013-01-04和之间的数据
# 使用标签获取横截面
df.loc[dates[0]] # dates 索引为零的行数据
# 使用标签选择多轴
df.loc[:,['A','B']] #取a到b两列纵行
# 显示标签切片, 包含两个端点
df.loc['20130102':'20130104',['A','B']] #显示20130102到20130104行数,然后a-b的纵行。
# 降低返回对象维度
df.loc['20130102',['A','B']]
# 获取标量值
df.loc[dates[0],'A'] #获取dates索引为零的的行行以及A列交叉的值。
# 按位置选择更多内容
df.iloc[3] #取出y轴索引为3的值,x轴数据,
df.iloc[3:5,0:2] #y轴,x轴范围过滤,索引3到索引5(不包括索引5),x轴(0-2)不包括2 通过整数片,类似于numpy / python
df.iloc[[1,2,4],[0,2]] #整数位置的位置列表,类似于numpy / python风格
#用于明确地切割行
df.iloc[1:3,:] # 输出y轴索引1到索引2,不包括索引3,然后x轴全部的值。
df.iloc[:,1:3] # 输出x轴索引1-2的值,y轴全部,用于明确地切分列
# 为了明确地获取一个值
df.iloc[1,1]
# 为了快速访问标量(等同于之前的方法)
df.iat[1,1]
# 使用单个列的值来选择数据。
df[df.A > 0]
# 从满足布尔条件的DataFrame中选择值
df[ df > 0 ]
# 使用isin()过滤方法
df2 = df.copy()
df2['E'] = ['one', 'one','two','three','four','three']
df2
df2[df2['E'].isin(['two','four'])]
#设置新列自动按索引排列数据
s1 = pd.Series([1,2,3,4,5,6], index=pd.date_range('20130102', periods=6))
s1
df.at[dates[0], 'A'] = 0 # 通过标签设置值
df.iat[0, 1] = 0 #按位置设置值
df.loc[:,'D'] = np.array([5] * len(df)) #通过分配一个numpy数组进行设置
df
# 条件设置操作。
df2 = df.copy()
df2[df2 > 0] = -df2
df2
# 熊猫主要使用这个值np.nan来表示缺失的数据
# Reindexing允许您更改/添加/删除指定轴上的索引。这将返回数据的副本。
df1 = df.reindex(index=dates[0:4], columns=list(df.columns) + ['E']) #添加E列,因为没赋值都是NaN!
df1
df1.loc[dates[0]:dates[1],'E'] = 1 # 在E列上y轴索引0,1设置值为1.
df1
# 删除任何缺少数据的行
df1.dropna(how='any')
# 填写缺少的数据
df1.fillna(value=6) #把NaN,无效的值,用6代替。
# 获取值是否nan的布尔标记
pd.isnull(df1)
# 运算一般操作不包括丢失的数据。
df.mean() #执行描述性统计
df.mean(1)#相同的操作在另一个轴上
# 用于运算的对象有不同的维度并需要对齐.除此之外,pandas会自动沿着指定维度计算.
s = pd.Series([1,3,5,np.nan,6,8],index=dates).shift(2) #索引保持不动,值被下移动两位
s
df
df.sub(s,axis='index')
# 在数据上使用函数
df.apply(np.cumsum)
df.apply(lambda x: x.max() - x.min())
# 直方图
s = pd.Series(np.random.randint(0, 7, size=10))
s
s.value_counts()
# 字符串方法
# 序列可以使用一些字符串处理方法很轻易操作数据组中的每个元素,比如以下代码片断。 注意字符匹配方法默认情况下通常使用正则表达式(并且大多数时候都如此). 更多信息请参阅字符串向量方法.
s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])
s.str.lower()
# pandas提供各种工具以简便合并序列,数据桢,和组合对象, 在连接/合并类型操作中使用多种类型索引和相关数学函数.
df = pd.DataFrame(np.random.randn(10, 4))
df
pieces = [df[:3], df[3:7], df[7:]]
pd.concat(pieces)
# SQL样式合并、
left = pd.DataFrame({'key': ['foo', 'foo'], 'lval': [1, 2]})
right = pd.DataFrame({'key': ['foo', 'foo'], 'rval': [4, 5]})
left
right
pd.merge(left, right, on='key')
# 添加行到数据
df = pd.DataFrame(np.random.randn(8, 4), columns=['A','B','C','D'])
df
s = df.iloc[3]
df.append(s, ignore_index=True)
# 分组将数据按某些标准分割为不同的,在每个独立组上应用函数组合结果为一个数据结构
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
# 分组然后应用函数统计总和存放到结果组
df.groupby('A').sum()
# 按多列分组为层次索引,然后应用函数
df.groupby(['A','B']).sum()
# 堆叠
tuples = list(zip(*[['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]))
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
df = pd.DataFrame(np.random.randn(8, 2), index=index, columns=['A', 'B'])
df2 = df[:4]
df2
# 堆叠 函数 “压缩” 数据桢的列一个级别.
stacked = df2.stack()
stacked
# 被“堆叠”数据桢或序列(有多个索引作为索引), 其堆叠的反向操作是未堆栈, 上面的数据默认反堆叠到上一级别:
stacked.unstack()
stacked.unstack(1)
stacked.unstack(0)
# 数据透视表
df = pd.DataFrame({'A' : ['one', 'one', 'two', 'three'] * 3,
'B' : ['A', 'B', 'C'] * 4,
'C' : ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 2,
'D' : np.random.randn(12),
'E' : np.random.randn(12)})
df
#x轴列字段为C,y轴索引为,AB,值为D字段
pd.pivot_table(df, values='D', index=['A', 'B'], columns=['C'])
# 时间序列,pandas有易用,强大且高效的函数用于高频数据重采样转换操作
rng = pd.date_range('1/1/2012', periods=100, freq='S')
ts = pd.Series(np.random.randint(0, 500, len(rng)), index=rng)
ts.resample('5Min', how='sum')
# 时区表示
rng = pd.date_range('3/6/2012 00:00', periods=5, freq='D')
ts = pd.Series(np.random.randn(len(rng)), rng)
ts
ts_utc = ts.tz_localize('UTC')
ts_utc
# 转换到其它时区
ts_utc.tz_convert('US/Eastern')
# 转换不同的时间跨度
rng = pd.date_range('1/1/2012', periods=5, freq='M')
ts = pd.Series(np.random.randn(len(rng)), index=rng)
ts
ps = ts.to_period()
ps
ps.to_timestamp()
# 转换时段并且使用一些运算函数, 下例中, 我们转换年报11月到季度结束每日上午9点数据
prng = pd.period_range('1990Q1', '2000Q4', freq='Q-NOV')
ts = pd.Series(np.random.randn(len(prng)), prng)
ts.index = (prng.asfreq('M', 'e') + 1).asfreq('H', 's') + 9
ts.head()
# 分类
# 自版本0.15起, pandas可以在数据桢中包含分类
df = pd.DataFrame({"id":[1,2,3,4,5,6], "raw_grade":['a', 'b', 'b', 'a', 'a', 'e']})
# 转换原始类别为分类数据类型.
df["grade"] = df["raw_grade"].astype("category")
df["grade"]
# 重命令分类为更有意义的名称 (分配到Series.cat.categories对应位置!)
df["grade"].cat.categories = ["very good", "good", "very bad"]
# 重排顺分类,同时添加缺少的分类(序列 .cat方法下返回新默认序列)
df["grade"] = df["grade"].cat.set_categories(["very bad", "bad", "medium", "good", "very good"])
df["grade"]
# 类别列分组,并且也显示空类别
df.groupby("grade").size()
# 绘图
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts = ts.cumsum()
ts.plot()
# 在数据桢中,可以很方便的绘制带标签列:
df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index,columns=['A', 'B', 'C', 'D'])
df = df.cumsum()
plt.figure(); df.plot(); plt.legend(loc='best')
# 写入csv文件
df.to_csv('foo.csv')
# 读取csv文件
pd.read_csv('foo.csv')
# 写入HDF5存储
df.to_hdf('foo.h5','df')
# 读取HDF5存储
pd.read_hdf('foo.h5','df')
# 写入excel文件
df.to_excel('foo.xlsx', sheet_name='Sheet1')
# 读取excel文件
pd.read_excel('foo.xlsx', 'Sheet1', index_col=None, na_values=['NA'])
pandas基础
流处理
流处理,听起来很高大上啊,其实就是分块读取。有这么一些情况,有一个很大的几个G的文件,没办法一次处理,那么就分批次处理,一次处理1百万行,接着处理下1百万行,慢慢地总是能处理完的。
# 使用类似迭代器的方式
data=pd.read_csv(file, chunksize=1000000)
for sub_df in data:
print('do something in sub_df here')
索引
Series和DataFrame都是有索引的,索引的好处是快速定位,在涉及到两个Series或DataFrame时可以根据索引自动对齐,比如日期自动对齐,这样可以省去很多事。
缺失值
pd.isnull(obj)
obj.isnull()
将字典转成数据框,并赋予列名,索引
DataFrame(data, columns=['col1','col2','col3'...],
index = ['i1','i2','i3'...])
查看列名
DataFrame.columns
查看索引
DataFrame.index
重建索引
obj.reindex(['a','b','c','d','e'...], fill_value=0]
#按给出的索引顺序重新排序,而不是替换索引。如果索引没有值,就用0填充
#就地修改索引
data.index=data.index.map(str.upper)
列顺序重排(也是重建索引)
DataFrame.reindex[columns=['col1','col2','col3'...])`
#也可以同时重建index和columns
DataFrame.reindex[index=['a','b','c'...],columns=['col1','col2','col3'...])
重建索引的快捷键
DataFrame.ix[['a','b','c'...],['col1','col2','col3'...]]
重命名轴索引
data.rename(index=str.title,columns=str.upper)
#修改某个索引和列名,可以通过传入字典
data.rename(index={'old_index':'new_index'},
columns={'old_col':'new_col'})
查看某一列
DataFrame['state'] 或 DataFrame.state
查看某一行
需要用到索引
DataFrame.ix['index_name']
添加或删除一列
DataFrame['new_col_name'] = 'char_or_number'#删除行
DataFrame.drop(['index1','index2'...])
#删除列
DataFrame.drop(['col1','col2'...],axis=1)
#或del DataFrame['col1']
DataFrame选择子集
类型
|
说明
|
obj[val]
|
选择一列或多列
|
obj.ix[val]
|
选择一行或多行
|
obj.ix[:,val]
|
选择一列或多列
|
obj.ix[val1,val2]
|
同时选择行和列
|
reindx
|
对行和列重新索引
|
icol,irow
|
根据整数位置选取单列或单行
|
get_value,set_value
|
根据行标签和列标签选择单个值
|
针对series
obj[['a','b','c'...]]
obj['b':'e']=5
针对dataframe
#选择多列
dataframe[['col1','col2'...]]
#选择多行
dataframe[m:n]
#条件筛选
dataframe[dataframe['col3'>5]]
#选择子集
dataframe.ix[0:3,0:5]
dataframe和series的运算
会根据 index 和 columns 自动对齐然后进行运算,很方便啊
方法
|
说明
|
add
|
加法
|
sub
|
减法
|
div
|
除法
|
mul
|
乘法
|
#没有数据的地方用0填充空值
df1.add(df2,fill_value=0)
# dataframe 与 series 的运算
dataframe - series
规则是:
-------- -------- |
| | | | |
| | -------- |
| | |
| | v
--------
#指定轴方向
dataframe.sub(series,axis=0)
规则是:
-------- ---
| | | | ----->
| | | |
| | | |
| | | |
-------- ---
apply函数
f=lambda x:x.max()-x.min()
#默认对每一列应用
dataframe.apply(f)
#如果需要对每一行分组应用
dataframe.apply(f,axis=1)
排序和排名
#默认根据index排序,axis = 1 则根据columns排序
dataframe.sort_index(axis=0, ascending=False)
# 根据值排序
dataframe.sort_index(by=['col1','col2'...])
#排名,给出的是rank值
series.rank(ascending=False)
#如果出现重复值,则取平均秩次
#在行或列上面的排名
dataframe.rank(axis=0)
描述性统计
方法
|
说明
|
count
|
计数
|
describe
|
给出各列的常用统计量
|
min,max
|
最大最小值
|
argmin,argmax
|
最大最小值的索引位置(整数)
|
idxmin,idxmax
|
最大最小值的索引值
|
quantile
|
计算样本分位数
|
sum,mean
|
对列求和,均值
|
mediam
|
中位数
|
mad
|
根据平均值计算平均绝对离差
|
var,std
|
方差,标准差
|
skew
|
偏度(三阶矩)
|
Kurt
|
峰度(四阶矩)
|
cumsum
|
累积和
|
Cummins,cummax
|
累计组大致和累计最小值
|
cumprod
|
累计积
|
diff
|
一阶差分
|
pct_change
|
计算百分数变化
|
唯一值,值计数,成员资格
obj.unique()
obj.value_count()
obj.isin(['b','c'])
处理缺失值
# 过滤缺失值
# 只要有缺失值就丢弃这一行
dataframe.dropna()
#要求全部为缺失才丢弃这一行
dataframe.dropna(how='all')
# 根据列来判断
dataframe.dropna(how='all',axis=1)
# 填充缺失值
#1.用0填充
df.fillna(0)
#2.不同的列用不同的值填充
df.fillna({1:0.5, 3:-1})
#3.用均值填充
df.fillna(df.mean())
# 此时axis参数同前面,
将列转成行索引
df.set_index(['col1','col2'...])
数据清洗,重塑
合并数据集
# 取 df1,df2 都有的部分,丢弃没有的# 默认是inner的连接方式
pd.merge(df1,df2, how='inner')
#如果df1,df2的连接字段名不同,则需要特别指定
pd.merge(df1,df2,left_on='l_key',right_on='r_key')
#其他的连接方式有 left,right, outer等。
# 如果dataframe是多重索引,根据多个键进行合并
pd.merge(left, right, on=['key1','key2'],how = 'outer')
#合并后如果有重复的列名,需要添加后缀
pd.merge(left, right, on='key1', suffixes=('_left','_right'))
索引上的合并
#针对dataframe中的连接键不是列名,而是索引名的情况。
pd.merge(left, right, left_on = 'col_key', right_index=True)
#即左边的key是列名,右边的key是index。
#多重索引
pd.merge(left, right, left_on=['key1','key2'], right_index=True)
dataframe的join方法
#实现按索引合并。#其实这个join方法和数据库的join函数是以一样的理解
left.join(right, how='outer')
#一次合并多个数据框
left.join([right1,right2],how='outer')
轴向连接(更常用)
连接:concatenation绑定:binding堆叠:stacking
列上的连接
np.concatenation([df1,df2],axis=1) #np包
pd.concat([df1,df2], axis=1) #pd包
#和R语言中的 cbind 是一样的
#如果axis=0,则和 rbind 是一样的#索引对齐,没有的就为空
# join='inner' 得到交集
pd.concat([df1,df2], axis=1, join='innner')
# keys 参数,还没看明白
# ignore_index=True,如果只是简单的合并拼接而不考虑索引问题。
pd.concat([df1,df2],ignore_index=True)
合并重复数据
针对可能有索引全部或者部分重叠的两个数据集
填充因为合并时索引赵成的缺失值
where函数
#where即if-else函数
np.where(isnull(a),b,a)
combine_first方法
#如果a中值为空,就用b中的值填补
a[:-2].combine_first(b[2:])
#combine_first函数即对数据打补丁,用df2的数据填充df1中的缺失值
df1.combine_first(df2)
重塑层次化索引
stact:将数据转为长格式,即列旋转为行unstack:转为宽格式,即将行旋转为列
result=data.stack()
result.unstack()
长格式转为宽格式
pivoted = data.pivot('date','item','value')
#前两个参数分别是行和列的索引名,最后一个参数则是用来填充dataframe的数据列的列名。如果忽略最后一个参数,得到的dataframe会带有层次化的列。
透视表
table = df.pivot_table(values=["Price","Quantity"],
index=["Manager","Rep"],
aggfunc=[np.sum,np.mean],
margins=True))
#values:需要对哪些字段应用函数#index:透视表的行索引(row)#columns:透视表的列索引(column)#aggfunc:应用什么函数#fill_value:空值填充#margins:添加汇总项
#然后可以对透视表进行筛选
table.query('Manager == ["Debra Henley"]')
table.query('Status == ["pending","won"]')
移除重复数据
# 判断是否重复
data.duplicated()`
#移除重复数据
data.drop_duplicated()
#对指定列判断是否存在重复值,然后删除重复数据
data.drop_duplicated(['key1'])
交叉表
是一种用于计算分组频率的特殊透视表.
注意,只对离散型的,分类型的,字符型的有用,连续型数据是不能计算频率这种东西的。
pd.crosstab(df.col1, df.col2, margins=True)
类似vlookup函数
利用函数或映射进行数据转换
#1.首先定义一个字典
meat_to_animal={
'bacon':'pig',
'pulled pork':'pig',
'honey ham':'cow'
}
#2.对某一列应用一个函数,或者字典,顺便根据这一列的结果创建新列
data['new_col']=data['food'].map(str.lower).map(meat_to_animal)
替换值
data.replace(-999,np.na)
#多个值的替换
data.replace([-999,-1000],np.na)
#对应替换
data.replace([-999,-1000],[np.na,0])
#对应替换也可以传入一个字典
data.replace({-999:np.na,-1000:0})
离散化
#定义分割点
bins=[20,40,60,80,100]
#切割
cats = pd.cut(series,bins)
#查看标签
cats.labels
#查看水平(因子)
cats.levels
#区间计数
pd.value_count(cats)
#自定义分区的标签
group_names=['youth','youngAdult','MiddleAge','Senior']
pd.cut(ages,bins,labels=group_names)
分位数分割
data=np.random.randn(1000)
pd.qcut(data,4) #四分位数
#自定义分位数,包含端点
pd.qcut(data,[0,0.3,0.5,0.9,1])
异常值
#查看各个统计量
data.describe()
#对某一列
col=data[3]
col[np.abs(col)>3]
#选出全部含有“超过3或-3的值的行
data[(np.abs(data)>3).any(1)]
#异常值替换
data[np.abs(data)>3]=np.sign(data)*3
抽样
#随机抽取k行
df.take(np.random.permutation(len(df))[:k])
#随机抽取k行,但是k可能大于df的行数#可以理解为过抽样了
df.take(np.random.randint(0,len(df),size=k))
数据摊平处理
相当于将类别属性转成因子类型,比如是否有车,这个字段有3个不同的值,有,没有,过段时间买,那么将会被编码成3个字段,有车,没车,过段时间买车,每个字段用0-1二值填充变成数值型。
#对摊平的数据列增加前缀
dummies = pd.get_dummies(df['key'],prefix='key')
#将摊平产生的数据列拼接回去
df[['data1']].join(dummies)
字符串操作
# 拆分
strings.split(',')
#根据正则表达式切分
re.split('s+',strings)
# 连接'a'+'b'+'c'...
或者
'+'.join(series)
# 判断是否存在's' in strings`
strings.find('s')
# 计数
strings.count(',')
# 替换
strings.replace('old','new')
# 去除空白字符
s.strip()
正则表达式
正则表达式需要先编译匹配模式,然后才去匹配查找,这样能节省大量的CPU时间。
re.complie:编译findall:匹配所有search:只返回第一个匹配项的起始和结束地址match:值匹配字符串的首部sub:匹配替换,如果找到就替换
#原始字符串
#编译匹配模式,IGNORECASE可以在使用的时候对大小写不敏感
pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'
regex = re.compile(pattern,flags=re.IGNORECASE)
#匹配所有
regex.findall(strings)
#使用search
m = regex.search(strings) #获取匹配的地址
strings[m.start():m.end()]
#匹配替换
regex.sub('new_string', strings)
根据模式再切分
将模式切分,也就是将匹配到的进一步切分,通过pattern中的括号实现.
pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\.([A-Z]{2,4})'
regex = re.compile(pattern)
regex.findall(strings)
#如果使用match
m=regex.match(string)
m.groups()
#效果是这样的
#获取 list-tuple 其中的某一列
matches.get(i)
分组聚合,计算
group_by技术
# 根据多个索引分组,然后计算均值
means = df['data1'].groupby([df['index1'],df['index2']).mean()
# 展开成透视表格式
means.unstack()
分组后价将片段做成一个字典
pieces = dict(list(df.groupby('index1')))
pieces['b']
groupby默认是对列(axis=0)分组,也可以在行(axis=1)上分组
语法糖,groupby的快捷函数
df.groupby('index1')['col_names']
df.groupby('index1')[['col_names']]
#是下面代码的语法糖
df['col_names'].groupby(df['index1'])
df.groupby(['index1','index2'])['col_names'].mean()
通过字典或series进行分组
people = DataFrame(np.random.randn(5, 5),
columns=['a', 'b', 'c', 'd', 'e'],
index=['Joe', 'Steve', 'Wes', 'Jim','Travis'])
# 选择部分设为na
people.ix[2:3,['b','c']]=np.na
mapping = {'a': 'red', 'b': 'red', 'c': 'blue',
'd': 'blue', 'e': 'red', 'f' : 'orange'}
people.groupby(mapping,axis=1).sum()
通过函数进行分组
#根据索引的长度进行分组
people.groupby(len).sum()
数据聚合
使用自定义函数
## 对所有的数据列使用自定义函数
df.groupby('index1').agg(myfunc)
#使用系统函数
df.groupby('index1')['data1']describe()
根据列分组应用多个函数
#分组
grouped = df.groupby(['col1','col2'])
#选择多列,对每一列应用多个函数
grouped['data1','data2'...].agg(['mean','std','myfunc'])
对不同列使用不同的函数
grouped = df.groupby(['col1','col2'])
#传入一个字典,对不同的列使用不同的函数#不同的列可以应用不同数量的函数
grouped.agg({'data1':['min','max','mean','std'],
'data2':'sum'})
分组计算后重命名列名
grouped = df.groupby(['col1','col2'])
grouped.agg({'data1':[('min','max','mean','std'),('d_min','d_max','d_mean','d_std')],
'data2':'sum'})
返回的聚合数据不要索引
df.groupby(['sex','smoker'], as_index=False).mean()
分组计算结果添加前缀
#对计算后的列名添加前缀
df.groupby('index1').mean().add_prefix('mean_')
将分组计算后的值替换到原数据框
#将函数应用到各分组,再将分组计算的结果代换原数据框的值#也可以使用自定义函数
df.groupby(['index1','index2'...]).transform(np.mean)
更一般化的apply函数
df.groupby(['col1','col2'...]).apply(myfunc)
df.groupby(['col1','col2'...]).apply(['min','max','mean','std'])
禁用分组键
分组键会跟原始对象的索引共同构成结果对象中的层次化索引
df.groupby('smoker', group_keys=False).apply(mean)
分组索引转成df的列
某些情况下,groupby的as_index=False参数并没有什么用,得到的还是一个series,这种情况一般是尽管分组了,但是计算需要涉及几列,最后得到的还是series,series的index是层次化索引。这里将series转成dataframe,series的层次化索引转成dataframe的列。
def fmean(df):
"""需要用两列才能计算最后的结果"""
skus=len(df['sku'].unique())
sums=df['salecount'].sum()
return sums/skus
#尽管禁用分组键,得到的还是series
salemean=data.groupby(by=['season','syear','smonth'],as_index=False).apply(fmean)
# 将series转成dataframe,顺便设置索引
sub_df = pd.DataFrame(salemean.index.tolist(),columns=salemean.index.names,index=salemean.index)
# 将groupby的结果和sub_df合并
sub_df['salemean']=salemean
桶分析与分位数
对数据切分段,然后对每一分段应用函数
frame = DataFrame({'col1':np.random.randn(1000),
'col2':np.random.randn(1000)})
#数据分段,创建分段用的因子#返回每一元素是属于哪一分割区间
factor = pd.cut(frame.col1, 4)
#分组计算,然后转成数据框形式
grouped = frame.col2.groupby(factor)
grouped.apply(myfunc).unstack()
用分组的均值填充缺失值
#自定义函数
fill_mean= lambda x:x.fillna(x.mean())
#分组填充
df.groupby(group_key).apply(fill_mean)
分组后不同的数据替换不同的值
#定义字典
fill_value = {'east':0.5, 'west':-1}
#定义函数
fill_func = lambda x:x.fillna(fill_value(x.name))
#分组填充
df.groupby(['index1','index2'...]).apply(fill_func)
sql操作
有时候觉得pandas很方便,但是有时候却很麻烦,不如SQL方便。因此pandas中也有一些例子,用pandas实现SQL的功能,简单的就不说了,下面说些复杂点的操作。
之所以说这个复杂的语句,是因为不想将这些数据操作分写在不同的语句中,而是从头到尾连续编码实现一个功能。
SQL复杂操作用到的主要函数是assign,简单说其实和join的功能是一样的,根据df1,df2的索引值来将df2拼接到df1上。
两个函数是query,也听方便的。
# 有一批销量数据,筛选出那些有2个月以上的销量产品的数据,说白了就是剔除那些新上市产品的数据# 方法是先统计每个产品的数据量,然后选出那些数据量>2的产品,再在数据表中选择这些产品# sku smonth# a 1# a 2# a 3# a 4# b 5# b 6# b 7# b 8# c 9# c 10# 按sku分组,统计smonth的次数,拼接到salecount中,然后查询cnt>2的
salecount.assign(cnt=salecount.groupby(['sku'])['smonth'].count()).query('cnt>2')
Numpy入门-官方直译
# 基础知识
# NumPy的主要对象是齐次多维数组。它是一个元素表(通常是数字),所有相同的类型,由正整数的元组索引。在NumPy维度被称为轴。轴的数量是等级。
#
# 例如,三维空间中一个点的坐标[1,2,1]是一个等级为1的数组,因为它具有一个坐标轴。该轴的长度为3.在下面的示例中,该数组具有等级2(它是二维的)。第一维(轴)的长度为2,第二维的长度为3。
#
# [[ 1. , 0. , 0 ],
# [ 0. , 1. , 2. ]]
# NumPy的数组类叫做ndarray。它也被别名数组所知 。请注意,numpy.array与标准Python库类array.array不一样,它只处理一维数组,并且提供较少的功能。ndarray对象的更重要的属性是:
#
# ndarray.ndim
# 阵列的轴数(维度)。在Python世界中,维度的数量被称为等级。
# ndarray.shape
# 数组的尺寸。这是一个整数的元组,指示每个维度中数组的大小。对于有n行m列的矩阵,形状将是(n,m)。形状元组的长度 因此是等级或维数 ndim。
# ndarray.size
# 数组元素的总数。这等于形状的元素的乘积。
# ndarray.dtype
# 一个描述数组中元素类型的对象。可以使用标准的Python类型创建或指定dtype。另外NumPy提供它自己的类型。numpy.int32,numpy.int16和numpy.float64是一些例子。
# ndarray.itemsize
# 数组中每个元素的字节大小。例如,类型为float64的元素的数组具有项目大小 8(= 64/8),而类型complex32中的一个具有项目大小 4(= 32/8)。这相当于ndarray.dtype.itemsize。
# ndarray.data
# 包含数组的实际元素的缓冲区。通常,我们不需要使用这个属性,因为我们将使用索引设施访问数组中的元素。
import numpy as np #可用来存储和处理大型矩阵的工具
from numpy import pi
import matplotlib.pyplot as plt
a = np.arange(15).reshape(3, 5) # 默认是从生成0-14个数字,分成三组,每组5个元素。
a
a.shape #数组的尺寸
a.ndim #阵列的轴数
a.dtype.name #一个描述数组中元素类型的对象
a.itemsize #数组中每个元素的字节大小
a.size #数组元素的总数
type(a)
b = np.array([6, 7, 8]) #创建一个数组
b
b.dtype
type(b) #获取变量b的数据类型
np.array([(1.5, 2, 3), (4, 5, 6)]) #数组将序列序列转换成二维数组,将序列序列转换成三维数组,等等
np.array([[1, 2], [3, 4]], dtype=complex) #数组的类型也可以在创建时明确指定:
#----NumPy提供了几个函数来创建具有初始占位符内容的数组。 这样可以最大限度地减少增加阵列的成本 ----#
np.zeros((3,4)) #创建全是零的二维,三组4列的元素。默认情况下,创建的数组的dtype是float64。
np.ones((2,3,4), dtype=np.int16) #创建全是1的三维数组,分两组,4列。
np.empty((2,3))#空函数创建一个数组,其初始内容是随机的,取决于内存的状态
np.arange(10, 30, 5) #返回一个范围数组数组
np.linspace( 0, 2, 9 ) #arange与浮点参数一起使用时,由于有限的浮点精度,获得不到元素的数量。 使用函数linspace作为参数来接收我们想要的元素的数量
x = np.linspace( 0, 2*pi, 100 ) #用于评估许多点的功能
f = np.sin(x)
np.arange(6) #一维数组
np.arange(12).reshape(4,3) #二维数组
np.arange(24).reshape(2,3,4) #三维数组
np.arange(10000) #如果数组太大而无法打印,NumPy会自动跳过数组的中心部分,只打印角点:
#数组上的算术运算符应用于元素。 一个新的数组被创建并填充结果
a = np.array([20, 30, 40, 50])
b = np.arange(4)
b
a-b
b**2
10*np.sin(a)
a<35
#与许多矩阵语言不同,运算符 *在NumPy数组中以元素形式操作。 矩阵乘积可以使用点函数或方法执行:
A = np.array( [[1,1],[0,1]] )
B = np.array( [[2,0],[3,4]] )
A*B
A.dot(B) #所得到的数组中的每个元素为,第一个矩阵中与该元素行号相同的元素与第二个矩阵与该元素列号相同的元素,两两相乘后再求和。
#A第一行元素:[1,1] * B第一列元素 [2,3] = 1*2 +1*3 = 5 =X = array([[X, Y], [X1, Y1]])
#A第一行元素:[1,1] * B第二列元素 [0,4] = 1*0 +1*4 = 4 =Y = array([[X, Y], [X1, Y1]])
#A第二行元素:[0,1] * B第一列元素 [2,3] = 0*2 +1*3 = 3 =x1 = array([[X, Y], [X1, Y1]])
#A第二行元素:[0,1] * B第二列元素 [0,4] = 0*0 +1*4 = 4 =y1 = array([[X, Y], [X1, Y1]])
# 最终输出结果:array([[5, 4], [3, 4]])
###############################################################################################################
#例如+ =和* =)适当地修改现有数组,而不是创建一个新数组。
a = np.ones((2,3), dtype=int)
b = np.random.random((2, 3))
a *= 3
a
b += a
b
a += b #报错,因为b不会自动转换为整数类型
#在使用不同类型的数组时,结果数组的类型对应于更更精确的数组(称为上传)。
a = np.ones(3, dtype=np.int32)
b = np.linspace(0, pi, 3)
b.dtype.name
c = a+b
c
c.dtype.name
d = np.exp(c*1j) #计算各元素的指数值
d
d.dtype.name
#许多一元运算,比如计算数组中所有元素的总和,都是作为ndarray类的方法来实现的。
a = np.random.random((2,3))
a
a.sum()
a.min()
a.max()
#通过指定轴参数,您可以沿着数组的指定轴应用操作
b = np.arange(12).reshape(3, 4)
b
b.sum(axis=0)#每列的总和
b.min(axis=1)#每行最小的数
b.cumsum(axis=1)#每行的累计和,每行除开头外,第二个数是开头数+本身,进行累计。第三个数=第二个数+第三个数
#常用的数学函数,如sin,cos和exp。 在NumPy中,这些被称为“通用函数”(ufunc)
B = np.arange(3)
B
np.exp(B)
np.sqrt(B)
C = np.array([2., -1., 4.])
np.add(B, C)
#一维数组可以被索引,切片和迭代,就像列表和其他Python序列一样。
a = np.arange(10)**3
a
a[2]
a[2:5]
a[:6:2] = -1000 #相当于[0:6:2] = -1000; 从开始到第6位,独占,每第二个元素设置为-1000
a
a[::-1] #把a反向输出
for i in a:
print(i ** (1 / 3.))
#多维数组每个轴可以有一个索引。 这些索引用逗号分隔: [y的索引:x的索引] =[y+1:x+1]
def f(x,y):
return 10 * x + y
b = np.fromfunction(f,(5,4),dtype=int) #以f函数式创建数组 ,创建整数数组,y轴为5,x轴为4的数组,
b
b[2, 3]#索引是从零开始,y轴=3,x轴为4 的数为=23
b[0:5, 1] #第二列中的每一行,0:5 是从y轴的取值范围,索引:1 相当于x轴的第二列、
b[ : ,1] #相当于b[0:5, 1],不给取值范围,默认去x轴第二列
b[1:3, :] #第二行和第三行中的每一列。
#当提供的索引数量少于轴数时,缺失的索引被认为是完整的切片:
b[-1] #最后一行 相当于b [-1 ,:]
# a 3D array (two stacked 2D arrays)
c = np.array( [[[ 0, 1, 2], [ 10, 12, 13]],[[100,101,102],[110,112,113]]])
c.shape
c[1,...] #同c [1,:,]或c [1]
c[...,2] #与c [:,:,2]相同
#迭代多维数组是相对于第一个轴完成的:
for row in b:
print(row)
#对数组中的每个元素执行操作,可以使用flat属性,该属性是数组中所有元素的迭代器
for element in b.flat:
print(element)
a = np.floor(10*np.random.random((3,4)))
a
a.shape
##数组的形状可以通过各种命令来改变
a.ravel()#返回展开的数组变成一维度。
a.reshape(6,2) #返回具有修改形状的数组,y变成6行,x变成2列。
a.T #返回数组,转置 x和y轴互换。
a.T.shape
a.shape
a.resize((2,6)) #y轴变两行。x轴变6列。
a
a.reshape(3,-1)#y轴变3行。x轴其-1,会自动计算x轴的列数。
#几个阵列可以沿不同的轴堆叠在一起:
a = np.floor(10*np.random.random((2,2)))
a
b = np.floor(10*np.random.random((2,2)))
b
np.vstack((a,b)) #b数组拼接在a数组的y轴的负方向上
np.hstack((a,b)) #b数组拼接在a数组的x轴的正方向上
#函数column_stack将 一维数组作为列叠加到2维数组中。它相当于仅用于一维数组的vstack:
from numpy import newaxis
np.column_stack((a,b)) # 把a的x和b的x轴的第一行和第二行分别拼接。
a = np.array([4.,6.])
b = np.array([3.,8.])
a[:,newaxis] #这允许有一个2D列向量,
np.column_stack((a[:,newaxis],b[:,newaxis]))
np.vstack((a[:,newaxis],b[:,newaxis])) #把a,b的x变成y,然后进行串联拼接
np.r_[1:4, 0, 4]
#使用hsplit,可以通过指定要返回的相同形状的数组的数量,或通过指定分割应该发生之后的列来沿着其横轴拆分数组:
a = np.floor(10*np.random.random((2,12)))
a
np.hsplit(a, 3) # 沿着x轴拆分成3列(4,4,4)
np.hsplit(a,(3,4)) # 沿着x轴拆分成3列,然后再把第四列拆分为一组。由(4,4,4)变(3,1,8)
#当操作和操作数组时,它们的数据有时会被复制到一个新的数组中,这通常是初学者混淆的来源。有三种情况:
a = np.arange(12)
b = a # 不创建新对象
b is a
b.shape = 3, 4 ##改变形状
a.shape
#Python将可变对象作为引用传递,所以函数调用不会复制。
def f(x):
print(id(x))
id(a) #id是对象的唯一标识符
f(a)
c = a.view()
c is a
c.base is a #c是由拥有的数据的视图
c.flags.owndata
c.shape = 2,6 # 一个的形状不改变
a.shape
c[0,4] = 1234 # a的数据变化
a
s = a[ : , 1:3]
# 为了清晰起见,添加了#个空格; 也可以写成“s = a [:,1:3]”
s[:] = 10 #s [:]是s的视图。注意S = 10和s之间的差[:] = 10
a
#########深复制;该复制方法使阵列及其数据的完整副本。############
d = a.copy() #创建新数据的新数组对象
d is a
d.base is a # d不与分享任何
d[0,0] = 9999
a
#常用的函数大全
# 数组创建
#--- arange, array, copy, empty, empty_like, eye, fromfile,
#--- fromfunction, identity, linspace, logspace, mgrid, ogrid, ones, ones_like,
#--- r, zeros, zeros_like
#转换
#--- ndarray.astype, atleast_1d, atleast_2d, atleast_3d, mat
# 手法
# --- array_split, column_stack, concatenate, diagonal, dsplit,dstack, hsplit, hstack,
# --- ndarray.item, newaxis, ravel, repeat, reshape, resize,
# --- squeeze, swapaxes, take, transpose, vsplit, vstack
#问题
#--- all, any, nonzero, where
# 函数指令
#--- argmax, argmin, argsort, max, min, ptp, searchsorted, sort
# 操作
#--- choose, compress, cumprod, cumsum, inner, ndarray.fill, imag, prod, put, putmask, real, sum
# 基本统计
#--- cov, mean, std, var
# 基本的线性代数
#--- cross, dot, outer, linalg.svd, vdot
# Numpy的API
a = np.arange(12)**2 # 前12个平方数
i = np.array( [ 1,1,3,8,5 ] ) # 一个索引的阵列
a[i] # 的在位置上的元件我
j = np.array( [ [ 3, 4], [ 9, 7 ] ] ) # 索引的二维阵列
a[j] # 相同的形状为J
# -----当索引数组a是多维时,单个索引数组指向a的第一维。 以下示例通过使用调色板将标签图像转换为彩色图像来显示此行为。--------#
palette = np.array( [ [0,0,0], # 黑色
[255,0,0], # 红色
[0,255,0], # 绿色
[0,0,255], # 蓝色
[255,255,255] ] ) # 白色
image = np.array( [ [ 0, 1, 2, 0 ], # 每一值对应于在调色板中的颜色
[ 0, 3, 4, 0 ] ] )
palette[image] # (2,43)彩色图像
# 可以给一个以上的维度指标。每个维度的索引数组必须具有相同的形状。
a = np.arange(12).reshape(3,4)
a
i = np.array( [ [0,1], # 用于第一暗淡的指数
[1,2] ] )
j = np.array( [ [2,1], # 第二个暗淡的指数
[3,3] ] )
a[i,j] #i和j必须具有相同的形状,a(0,2) =2 a(1,1)=5 ,a(1,3) =7 ,a(2,3) =11 最终结果-->array([[ 2, 5],[ 7, 11]])
a[i,2]#i和j必须具有相同的形状,a(0,2) =2 a(1,2)=6 , a(1,2)=6 ,a(2,2) =10 最终结果-->array([[ 2, 6], [ 6, 10]])
a[:,j] # i.e., a[ : , j]
# 可以把i和j放在一个序列中(比如说一个列表),然后用列表进行索引。
l = [i,j]
a[l] # 等同于[i,j]
s = np.array([i,j])
a[s] # 出错,不能通过将i和j放入一个数组。
a[tuple(s)] # 相同作为[i,j]
# 数组索引的另一个常见用途是搜索时间相关系列的最大值:
time = np.linspace(20, 145, 5) # 时标
data = np.sin(np.arange(20)).reshape(5,4) # 4随时间变化的一系列
time
data
ind = data.argmax(axis=0) # 每个系列最大值的索引
ind
time_max = time[ind] # 对应于最大值的次数
data_max = data[ind, range(data.shape[1])] # => data[ind[0],0], data[ind[1],1]...
time_max
data_max
np.all(data_max == data.max(axis=0))
# 使用数组的索引作为分配给的目标:
a = np.arange(5)
a
a[[1,3,4]] = 2
a
# 当索引列表包含重复时,分配会执行好几次,而留下最后一个值
a = np.arange(5)
a #输出array([0, 1, 2, 3, 4])
#索引0 更为为1,第二次索引更改为2,所以数组的a处的零索引取值为原数组的为2索引的值:2 ,然后索引2处的数改为索引3的数,
a[[0,0,2]]=[1,2,3]
a
# 这足够合理,但要小心如果你想使用Python的 + =构造,因为它可能不会做你期望的:
a = np.arange(5)
a[[0,0,2]]+=1
a
# 布尔索引最自然的方法就是使用与原始数组形状相同的布尔数组:
a = np.arange(12).reshape(3,4)
b = a > 4
b # b为具有的形状的布尔
a[b] # 一维数组与选定的元素
# 这个属性在作业中非常有用:
a[b] = 0 #'A'大于4的所有元素用零代替
a
# 使用布尔索引来生成Mandelbrot集的图像:
def mandelbrot( h,w, maxit=20 ):
"""返回Mandelbrot分形的图像大小(h,w )."""
y,x = np.ogrid[ -1.4:1.4:h*1j, -2:0.8:w*1j ]
c = x+y*1j
z = c
divtime = maxit + np.zeros(z.shape, dtype=int)
for i in range(maxit):
z = z**2 + c
diverge = z*np.conj(z) > 2**2 # 正在发偏离的人
div_now = diverge & (divtime==maxit) # 现在偏离的人
divtime[div_now] = i # 注意何时
z[diverge] = 2 # 避免偏离太多
return divtime
plt.imshow(mandelbrot(400,400))
plt.show()
# 用布尔值编制索引的第二种方法更类似于整数索引; 对于数组的每个维度,我们给出一个1D布尔数组,选择我们想要的切片:
a = np.arange(12).reshape(3,4)
a
b1 = np.array([False,True,True]) # 第一个dim选择
b1
b2 = np.array([True,False,True,False]) # 第二个dim选择
b2
a[b1,:] # 选择行(b1([False, True, True]),第一行不显示
a[b1] # 一样
a[:,b2] # 选择列
a[b1,b2] # 一个奇怪的事情要做
# ix_()函数:该ix_函数可用于不同的载体结合,以便获得对于每一个n-uplet结果。
# 例如,如果要计算从每个矢量a,b和c取得的所有三元组的所有a + b * c:
a = np.array([2,3,4,5])
b = np.array([8,5,4])
c = np.array([5,4,6,8,3])
ax,bx,cx = np.ix_(a,b,c)
ax
bx
cx
ax.shape, bx.shape, cx.shape
result = ax+bx*cx
result
# 你也可以按如下方式执行reduce:
def ufunc_reduce(ufct, *vectors):
vs = np.ix_(*vectors)
r = ufct.identity
for v in vs:
r = ufct(r,v)
return r
ufunc_reduce(np.add,a,b,c)
# 用字符串索引
# 线性代数
a = np.array([[1.0, 2.0], [3.0, 4.0]])
a
a.transpose() #x,y转换
np.linalg.inv(a)
u = np.eye(2) # 2×2矩阵; “眼睛”代表“我”
u
j = np.array([[0.0, -1.0], [1.0, 0.0]])
np.dot (j, j) # 矩阵产品
np.trace(u) # 返回数组的对角线的和。
y = np.array([[5.], [7.]])
np.linalg.solve(a, y)
np.linalg.eig(j)
# 参数:
# 方矩阵
# 返回
# 特征值,每个特征根据其多重性重复。
# 归一化的(单位“长度”)特征向量,
# 列`
v [:,i]
是对应的特征向量# 特征值`
w [i]
`。# 技巧和提示: 要更改数组的尺寸,可以省略其中一个尺寸,然后自动推导出这些尺寸
a = np.arange(30)
a.shape = 2,-1,3 # -1表示“任何需要”
a.shape
a
# 矢量堆叠
x = np.arange(0,10,2) # x=([0,2,4,6,8])
y = np.arange(5) # y=([0,1,2,3,4])
m = np.vstack([x,y]) # m=([[0,2,4,6,8],
# [0,1,2,3,4]])
xy = np.hstack([x,y]) # xy =([0,2,4,6,8,0,1,2,3,4])
# 直方图
# #构建10000个正常偏离的矢量方差0.5 ^ 2和平均2
mu, sigma = 2, 0.5
v = np.random.normal(mu,sigma,10000)
# #绘制一个规格化的直方图与50箱
plt.hist(v, bins=50, normed=1) # matplotlib版本(图)
plt.show()
# #用numpy计算直方图,然后绘制
(n, bins) = np.histogram(v, bins=50, normed=True) # #NumPy版本(无图)
plt.plot(.5*(bins[1:]+bins[:-1]), n)
plt.show()