练习题Kesci链接: link
思路:
chipo['item_name']
,则产生一个Series(不能传入多个列名);chipo[['item_name','quantity']]
,则产生一个DataFrame。as_index=False
表示分组键不作为index,如果传入group_keys=False
在后面的运算中会把分组键重新置为index——不清楚什么原因).agg({'quantity':sum})
[['quantity']].sum()
inplace=True
实现原地排序统计不重复的对象的个数
答案:chipo['item_name'].nunique()
我:len(chipo['item_name'].unique())
chipo['item_price']
中每个对象的格式是string(‘$’+数字),如果直接用.astype(float)
则会出错,因为str无法转换成为float。
解决办法:利用可调用函数处理每个对象,并将函数传入apply。
dollarizer = lambda x: float(x[1:-1])#去除'$'符号并将数字传唤成为float
chipo['item_price'].apply(dollarizer)
round()
返回括号内浮点数的四舍五入值。
思路:
chipo[['order_id','sub_total']]
.groupby(by=['order_id'])
.agg({'sub_total':'sum'})
['sub_total']
.mean()
.shape(0)
DataFrame的shape函数,输出括号内(0代表0轴,1代表1轴…)的大小。
.sort_values(by=['A','B'])
sort_value函数按照A,B的先后顺序对A,B先后排序。
处理字符串对象用str函数
答案:euro12[euro12.Team.str.startswith('G')]
我:euro12[euro12['Team'].apply(lambda x: x[0]=='G')]
.iloc
按整数索引选取子行和子列
loc
按轴标签(行名或列名)选取子行和子列
.isin()
函数可用于选取某一列中的几个对象所在的行作为行索引,函数返回的是bool类型的Series。
思路:
drinks.groupby('continent')
.spirit_servings
agg(['mean', 'min', 'max'])
datetime64
crime.Year = pd.to_datetime(crime.Year, format='%Y')
转换为时间数据类型(年份)
crime.set_index('Year', drop = True)
默认drop为True,如果drop=False则保留’Year’在原数据集中,不‘丢弃’。
答案:del crime['Total']
我:crime.drop(['Total'],axis=1)
答案更加方便
答案:crime.resample('10AS').sum()
该语句的作用是对时间的重采样(分组操作,跟groupby的作用类似)——每10年为一组,并对每组内的数据进行求和操作。
我(效果相同的代码):crime.groupby(pd.Grouper(freq='10AS')).sum()
使用了groupby对时间实现分组操作
注意Population这一列,若直接对其求和,是不正确的
思路:
crimes = crime.resample('10AS').sum()
population = crime['Population'].resample('10AS').max()
crimes['Population'] = population
目的:获取最大值的索引
代码实现:crime.idxmax(0)
笔记:pandas对象中的数据可以通过一些方式进行合并:
pandas.merge
可根据一个或多个键将不同DataFrame中的行连接起来。SQL或其他关系型数据库的用户对此应该会比较熟悉,因为它实现的就是数据库的join操作。pandas.concat
可以沿着一条轴将多个对象堆叠到一起。- 实例方法
combine_first
可以将重复数据拼接在一起,用一个对象中的值填充另一个对象中的缺失值。
data = pd.read_table(path6, sep = "\s+", parse_dates = [[0,1,2]])
parse_dates = [[0,1,2]]
的作用是:传入一个list of lists,合并0,1,2列的值作为一个日期列使用
思路:
def fix_century(x):
year = x.year - 100 if x.year > 1989 else x.year
return datetime.date(year, x.month, x.day)
data['Yr_Mo_Dy'] = data['Yr_Mo_Dy'].apply(fix_century)
datetime64[ns]
思路:
object
类型转换成datetime64[ns]
类型data["Yr_Mo_Dy"] = pd.to_datetime(data["Yr_Mo_Dy"])
data = data.set_index('Yr_Mo_Dy')
目的:统计每一列的缺失值数
代码实现:data.isnull().sum()
loc_stats
的数据框去计算并存储每个location的风速最小值,最大值,平均值和标准差答案代码实现:
loc_stats = pd.DataFrame()
loc_stats['min'] = data.min() # min
loc_stats['max'] = data.max() # max
loc_stats['mean'] = data.mean() # mean
loc_stats['std'] = data.std() # standard deviations
我的方法:data.agg({'min','max','mean','std'})
这种方法生成的index和columns刚好与答案相反了,而且agg函数不能对行(axis=1)传入多个函数,data.agg({'min','max','mean','std'},axis=1)
注意,1961年的1月和1962年的1月应该区别对待
答案思路:
data['date'] = data.index
data['month'] = data['date'].apply(lambda date: date.month)
data['year'] = data['date'].apply(lambda date: date.year)
data['day'] = data['date'].apply(lambda date: date.day)
.quary()
提取月份等于1所在的行。 january_winds = data.query('month == 1')
january_winds.loc[:,'RPT':"MAL"].mean()
我的方法: data[data.index.month==1].mean()
我的方法是通过索引提取月份等于1所在的行。
答案方法:依然是使用查询函数.quary()
提取月和日都等于1所在的行。
data.query('month == 1 and day == 1')
我的方法:使用时间重采样函数.resample()
,传入'AS'
代表按年重采样,使用.first()
代表数值用第一个值代替,也就是按1月1日的值填充。
data.resample('AS').first()
思路:
males = (titanic['Sex'] == 'male').sum()
females = (titanic['Sex'] == 'female').sum()
proportions = [males, females]
proportions
,第二个参数labels
对应数据集每个子集的标签,第三个参数shadow
设置扇形图是否有阴影效果(显得更立体),第四个参数colors
设置每个子集扇形块对应的颜色,第五个参数explode
设置扇形图每个扇形块与其他块分离开的大小(记得是使用小括号),第六个参数startangle
代表扇形图的起始角度,第七个参数autopct
自动在每个扇形块上标注百分比以及设置百分比显示的格式。plt.pie(
# using proportions
proportions,
# with the labels being officer names
labels = ['Males', 'Females'],
# with no shadows
shadow = False,
# with colors
colors = ['blue','red'],
# with one slide exploded out
explode = (0.15 , 0),
# with the start angle at 90%
startangle = 90,
# with the percent listed as a fraction
autopct = '%1.1f%%'
)
Fare
, 与乘客年龄和性别的散点图答案方法:lm = sns.lmplot(x = 'Age', y = 'Fare', data = titanic, hue = 'Sex', fit_reg=False)
答案使用了seaborn
的lmplot
,这是一种集合基础绘图与基于数据建立回归模型的绘图方法。设置了fit_reg=False
就是普通的散点图,不进行回归分析。
我的方法(普通散点图):sns.scatterplot(x='Age',y='Fare',data=titanic,hue='Sex')
我的方法只能绘制普通的散点图,参数hue
定义数据子集的变量。
绘制频率分布直方图方法:
binsVal = np.arange(0,600,10)
plt.hist(df, bins = binsVal)
这里有一个关键的参数是bins
,作用是设置连续的边界值(确定直方图x轴上每一条柱的边界),即直方图的分布区间[0,10],[10,20]。。。
查看DataFrame的每个列的数据类型:.dtypes
(记得后面有s)
查看Series的数据类型:dtype
(后面没有s)
我的方法(错误结果):,暂时不知道原因。pokemon.apply(lambda x: x.dtype)
apple.index.max() - apple.index.min()
输出timedelta
类型
转化为天数的int型输出需要:(apple.index.max() - apple.index.min()).days
答案方法:iris = pd.read_csv(path10,names = ['sepal_length','sepal_width', 'petal_length', 'petal_width', 'class'])
使用pd.read_csv
设置列名需要传入参数names=
而不是columns=
。
我的方法:iris.columns=['sepal_length','sepal_width', 'petal_length', 'petal_width', 'class']
直接使用.columns
设置列名。
petal_length
的第10到19行设置为缺失值答案:iris.iloc[10:20,2:3] = np.nan
最好使用loc或iloc提取感兴趣的行和列。
我的方法(系统报Warning):iris['petal_length'][10:20]=np.nan
这种方法倾向于从DataFrame中复制相应的行和列,然后作修改。所以最好是用答案原地修改的方法。
代码实现:iris = iris.reset_index(drop = True)
因为reset_index
后,老的index默认会成为新的DataFrame中的一列。传入drop=True
则可以丢弃老的index,直接生成新的索引。