import numpy as np
import pandas as pd
from numpy import nan as NA
import re
# 1.判断缺失数据
string_data = pd.Series(['aardvark', 'artichoke', np.nan, 'avocado'])
print(string_data.isnull())
#滤除缺失数据
#对于一个Series,dropna返回一个仅含非空数据和索引值的Series
print(string_data.dropna())
#对于Dataframe,dropna默认丢弃任何含有缺失值的行
data = pd.DataFrame([[1., 6.5, 3.], [1., NA, NA],
[NA, NA, NA], [NA, 6.5, 3.]])
cleaned = data.dropna()
print(cleaned)
#传入how='all'将只丢弃全为NA的那些行:
print(data.dropna(how="all"))
#用这种方式丢弃列,只需传入axis=1即可
data[4] = NA
print(data.dropna(axis=1, how='all'))
#填充缺失数据
df = pd.DataFrame(np.random.randn(7, 3))
df.iloc[:4, 1] = NA
df.iloc[:2, 2] = NA
print(df.fillna(0))#所有NA都变为0
print(df.fillna({1: 0.5, 2: 0}))#第一列填充0.5,第二列填充0
df.fillna(0,inplace=True)#不返回新对象,修改本身
print(df)
#对reindexing有效的那些插值方法也可用于fillna
df = pd.DataFrame(np.random.randn(6, 3))
df.iloc[2:, 1] = NA
df.iloc[4:, 2] = NA
print(df.fillna(method='ffill', limit=2))#数据向前填充,limit设置为只填充两行
#2 数据转换
#移除重复数据
data = pd.DataFrame({'k1': ['one', 'two'] * 3 + ['two'],
'k2': [1, 1, 2, 3, 3, 4, 4]})
#DataFrame的duplicated方法返回一个布尔型Series,表示各行是否是重复行(前面出现过的行)
print(data.duplicated())
#drop_duplicates方法,它会返回一个DataFrame,重复的数组会标为False
print(data.drop_duplicates())#这里最后一行和倒数第二行重复,就直接false不返回
data['v1'] = range(7)
print(data.drop_duplicates(['k1']))#只判断k1列是否重复
#duplicated和drop_duplicates默认保留的是第一个出现的值组合。传入keep='last'则保留最后一个
print(data.drop_duplicates(['k1', 'k2'], keep='last'))#这里倒数第一行和倒数第二行重复,然后保留最后一个,即倒数第一行
#利用函数或映射进行数据转换
data = pd.DataFrame({'food': ['bacon', 'pulled pork', 'bacon',
'Pastrami', 'corned beef', 'Bacon',
'pastrami', 'honey ham', 'nova lox'],
'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
meat_to_animal = {
'bacon': 'pig',
'pulled pork': 'pig',
'pastrami': 'cow',
'corned beef': 'cow',
'honey ham': 'pig',
'nova lox': 'salmon'
}
#Series的map方法可以接受一个函数或含有映射关系的字典型对象,但是这里有一个小问题,即有些肉类的首字母大写了,而另一些则没有。因此,我们还需要使用Series的str.lower方法,将各个值转换为小写
lowercased = data['food'].str.lower()
data['animal'] = lowercased.map(meat_to_animal)
print(data)
#替换值
data = pd.Series([1., -999., 2., -999., -1000., 3.])
#-999这个值可能是一个表示缺失数据的标记值。要将其替换为pandas能够理解的NA值,我们可以利用replace来产生一个新的Series(除非传入inplace=True)
print(data.replace(-999, np.nan))
#如果你希望一次性替换多个值,可以传入一个由待替换值组成的列表以及一个替换值
print(data.replace([-999,-1000], np.nan))
#要让每个值有不同的替换值,可以传递一个替换列表:
print(data.replace([-999,-1000], [np.nan,"hh"]))
#传入的参数也可以是字典:
print(data.replace({-999: np.nan, -1000: 0}))
#离散化和面元划分
#为了便于分析,连续数据常常被离散化或拆分为“面元”(bin)。假设有一组人员数据,而你希望将它们划分为不同的年龄组
ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
bins = [18, 25, 35, 60, 100]
#接下来将这些数据划分为“18到25”、“26到35”、“35到60”以及“60以上”几个面元。要实现该功能,你需要使用pandas的cut函数
cats = pd.cut(ages, bins)
print(cats)
#pd.value_counts(cats)是pandas.cut结果的面元计数。
print(pd.value_counts(cats))
#你可 以通过传递一个列表或数组到labels,设置自己的面元名称
group_names = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior']
print(pd.value_counts(pd.cut(ages, bins, labels=group_names)))
#检测和过滤异常值
data = pd.DataFrame(np.random.randn(1000, 4))
print(data.describe())#describe()函数返回这个data的简要表述,像count、min、max等
#假设你想要找出某列中绝对值大小超过3的值
col = data[2]
print(col[np.abs(col) > 3])#返回data第二列绝对值大于3的数
#要选出全部含有“超过3或-3的值”的行,你可以在布尔型DataFrame中使用any方法
print(data[(np.abs(data) > 3).any(1)])
#根据这些条件,就可以对值进行设置。下面的代码可以将值限制在区间-3到3以内
data[np.abs(data) > 3] = np.sign(data) * 3
print(data.describe())
#根据数据的值是正还是负,np.sign(data)可以生成1和-1
print(np.sign(data))
#排列和随机采样
#利用numpy.random.permutation函数可以轻松实现对Series或DataFrame的列的排列工作(permuting,随机重排序)
df = pd.DataFrame(np.arange(5 * 4).reshape((5, 4)))
sampler = np.random.permutation(5)
print(df,sampler)
#计算指标/哑变量
df = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'],
'data1': range(6)})
print(df)
#有时候,你可能想给指标DataFrame的列加上一个前缀,以便能够跟其他数据进行合并。get_dummies的prefix参数可以实现该功能
dummies = pd.get_dummies(df['key'], prefix='key')
print(dummies)
#3 字符串操作
#以逗号分隔的字符串可以用split拆分成数段
val = 'a,b, guido'
print(val.split(','))
#split常常与strip一起使用,以去除空白符(包括换行符)
pieces = [x.strip() for x in val.split(',')]
print(pieces)
#利用加法,可以将这些子字符串以双冒号分隔符的形式连接起来
first, second, third = pieces
print(first + '::' + second + '::' + third)
#但这种方式并不是很实用。一种更快更符合Python风格的方式是,向字符串"::"的join方法传入一个列表或元组
print("::".join(pieces))
#index方法返回字符所在的位置,但字符不存在会报错,find不会报错,会返回-1,rfind返回最后一个子串的第一个字符所在的位置
print(val.index('g'))
print(val.find(','))
print(val.rfind(','))
#count可以返回指定子串的出现次数
print(val.count(","))
#replace用于将指定模式替换为另一个模式。通过传入空字符串,它也常常用于删除模式
print(val.replace(',', '::'))
#正则表达式,常称作regex,python里用re模块处理,re模块的函数可以分为三个大类:模式匹配、替换以及拆分
#描述一个或多个空白符(制表符、空格、换行符等)的regex是\s+
text = "foo bar\t baz \tqux"
#调用re.split('\s+',text)时,正则表达式会先被编译,然后再在text上调用其split方法
print(re.split('\s+', text))
#如果只希望得到匹配regex的所有模式,则可以使用findall方法,match和search跟findall功能类似。findall返回的是字符串中所有的匹配项,而search则只返回第一个匹配项。
regex = re.compile('\s+')
print(regex.findall(text))
#[' ', '\t ', ' \t']
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步