14

Pandas 50题练习

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzI1MTE2ODg4MA%3D%3D&%3Bmid=2650072425&%3Bidx=1&%3Bsn=dc3af2992b01ff91111b09436d7365dc
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

受到numpy100题的启发,我们制作了pandas50题。

Pandas 是基于 NumPy 的一种数据处理工具,该工具为了解决数据分析任务而创建。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的函数和方法。这些练习着重DataFrame和Series对象的基本操作,包括数据的索引、分组、统计和清洗。

摩拳擦掌想做题试试手感的

点击“ 阅读原文 ”在线运行

参考资料 | 100-pandas-puzzles - GitHub | Pandas 百题大冲关

基本操作

  1. 导入 Pandas 库并简写为 pd,并输出版本号

import pandas as pd
pd.__version__
  1. 从列表创建 Series

arr = [0, 1, 2, 3, 4]
df = pd.Series(arr) # 如果不指定索引,则默认从 0 开始
df
  1. 从字典创建 Series

d = {'a':1,'b':2,'c':3,'d':4,'e':5}
df = pd.Series(d)
df
  1. 从 NumPy 数组创建 DataFrame

dates = pd.date_range('today',periods=6) # 定义时间序列作为 index
num_arr = np.random.randn(6,4) # 传入 numpy 随机数组
columns = ['A','B','C','D'] # 将列表作为列名
df = pd.DataFrame(num_arr, index = dates, columns = columns)
df
  1. 从CSV中创建 DataFrame,分隔符为“;”,编码格式为gbk

df = pd.read_csv('test.csv', encoding='gbk, sep=';')
  1. 从字典对象创建DataFrame,并设置索引

import numpy as np

data = {'animal': ['cat', 'cat', 'snake', 'dog', 'dog', 'cat', 'snake', 'cat', 'dog', 'dog'],
        'age': [2.5, 3, 0.5, np.nan, 5, 2, 4.5, np.nan, 7, 3],
        'visits': [1, 3, 2, 3, 2, 3, 1, 1, 2, 1],
        'priority': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}

labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
df = pd.DataFrame(data, index=labels)
df
  1. 显示 df 的基础信息,包括行的数量;列名;每一列值的数量、类型
df.info()
# 方法二
# df.describe()
  1. 展示 df 的前 3
df.iloc[:3]
# 方法二
#df.head(3)
  1. df
    animal
    age
    
df.loc[:, ['animal', 'age']]
# 方法二
# df[['animal', 'age']]
  1. [3, 4, 8]
    animal
    age
    
df.loc[df.index[[3, 4, 8]], ['animal', 'age']]
  1. 取出 age 值大于 3 的行
df[df['age'] > 3]
  1. 取出 age 值缺失的行
df[df['age'].isnull()]
  1. 取出 age2,4 间的行(不含)
df[(df['age']>2) & (df['age']>4)]
# 方法二
# df[df['age'].between(2, 4)]
  1. f
    age
    1.5
    
df.loc['f', 'age'] = 1.5
  1. 计算 visits 的总和
df['visits'].sum()
  1. 计算每个不同种类 animalage 的平均数
df.groupby('animal')['age'].mean()
  1. df 中插入新行 k ,然后删除该行
#插入
df.loc['k'] = [5.5, 'dog', 'no', 2]
# 删除
df = df.drop('k')
df
  1. 计算 df 中每个种类 animal 的数量
df['animal'].value_counts()
  1. 先按 age 降序排列,后按 visits 升序排列
df.sort_values(by=['age', 'visits'], ascending=[False, True])
  1. priority
    yes, no
    True, False
    
df['priority'] = df['priority'].map({'yes': True, 'no': False})
df
  1. animal
    snake
    python
    
df['animal'] = df['animal'].replace('snake', 'python')
df
  1. animal
    visits
    age
    visits
    
df.pivot_table(index='animal', columns='visits', values='age', aggfunc='mean')

进阶操作

  1. 有一列整数列A的DatraFrame,删除数值重复的行

df = pd.DataFrame({'A': [1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 7]})
print(df)
df1 = df.loc[df['A'].shift() != df['A']]
# 方法二
# df1 = df.drop_duplicates(subset='A')
print(df1)
  1. 一个全数值DatraFrame,每个数字减去该行的平均数

df = pd.DataFrame(np.random.random(size=(5, 3)))
print(df)
df1 = df.sub(df.mean(axis=1), axis=0)
print(df1)
  1. 一个有5列的DataFrame,求哪一列的和最小

df = pd.DataFrame(np.random.random(size=(5, 5)), columns=list('abcde'))
print(df)
df.sum().idxmin()
  1. 给定DataFrame,求 A 列每个值的前3的 B 的值的和
df = pd.DataFrame({'A': list('aaabbcaabcccbbc'),
                   'B': [12,345,3,1,45,14,4,52,54,23,235,21,57,3,87]})
print(df)
df1 = df.groupby('A')['B'].nlargest(3).sum(level=0)
print(df1)
  1. 给定DataFrame,有列 A, BA 的值在1-100(含),对 A 列每10步长,求对应的B的和
df = pd.DataFrame({'A': [1,2,11,11,33,34,35,40,79,99],
                   'B': [1,2,11,11,33,34,35,40,79,99]})
print(df)
df1 = df.groupby(pd.cut(df['A'], np.arange(0, 101, 10)))['B'].sum()
print(df1)
  1. 给定DataFrame,计算每个元素至左边最近的0(或者至开头)的距离,生成新列 y
df = pd.DataFrame({'X': [7, 2, 0, 3, 4, 2, 5, 0, 3, 4]})

izero = np.r_[-1, (df['X'] == 0).to_numpy().nonzero()[0]] # 标记0的位置
idx = np.arange(len(df))
df['Y'] = idx - izero[np.searchsorted(izero - 1, idx) - 1]
print(df)

# 方法二
# x = (df['X'] != 0).cumsum()
# y = x != x.shift()
# df['Y'] = y.groupby((y != y.shift()).cumsum()).cumsum()

# 方法三
# df['Y'] = df.groupby((df['X'] == 0).cumsum()).cumcount()
#first_zero_idx = (df['X'] == 0).idxmax()
# df['Y'].iloc[0:first_zero_idx] += 1
  1. 一个全数值的DataFrame,返回最大3个值的坐标

df = pd.DataFrame(np.random.random(size=(5, 3)))
print(df)
df.unstack().sort_values()[-3:].index.tolist()
  1. 给定DataFrame,将负值代替为同组的平均值

df = pd.DataFrame({'grps': list('aaabbcaabcccbbc'),
                   'vals': [-12,345,3,1,45,14,4,-52,54,23,-235,21,57,3,87]})
print(df)

def replace(group):
    mask = group<0
    group[mask] = group[~mask].mean()
    return group

df['vals'] = df.groupby(['grps'])['vals'].transform(replace)
print(df)
  1. 计算3位滑动窗口的平均值,忽略 NAN
df = pd.DataFrame({'group': list('aabbabbbabab'),
                    'value': [1, 2, 3, np.nan, 2, 3, np.nan, 1, 7, 3, np.nan, 8]})
print(df)

g1 = df.groupby(['group'])['value']
g2 = df.fillna(0).groupby(['group'])['value']

s = g2.rolling(3, min_periods=1).sum() / g1.rolling(3, min_periods=1).count()
s.reset_index(level=0, drop=True).sort_index()

Series 和 Datetime索引

  1. 创建Series s ,将2015所有工作日作为随机值的索引
dti = pd.date_range(start='2015-01-01', end='2015-12-31', freq='B')
s = pd.Series(np.random.rand(len(dti)), index=dti)

s.head(10)
  1. 所有礼拜三的值求和

s[s.index.weekday == 2].sum()
  1. 求每个自然月的平均数

s.resample('M').mean()
  1. 每连续4个月为一组,求最大值所在的日期

s.groupby(pd.Grouper(freq='4M')).idxmax()
  1. 创建2015-2016每月第三个星期四的序列

pd.date_range('2015-01-01', '2016-12-31', freq='WOM-3THU')

数据清洗

df = pd.DataFrame({'From_To': ['LoNDon_paris', 'MAdrid_miLAN', 'londON_StockhOlm',
                               'Budapest_PaRis', 'Brussels_londOn'],
              'FlightNumber': [10045, np.nan, 10065, np.nan, 10085],
              'RecentDelays': [[23, 47], [], [24, 43, 87], [13], [67, 32]],
                   'Airline': ['KLM(!)', '<Air France> (12)', '(British Airways. )',
                               '12. Air France', '"Swiss Air"']})
df
  1. FlightNumber 列中有些值缺失了,他们本来应该是每一行增加10,填充缺失的数值,并且令数据类型为整数
df['FlightNumber'] = df['FlightNumber'].interpolate().astype(int)
df
  1. From_To
    _
    From, To
    
temp = df.From_To.str.split('_', expand=True)
temp.columns = ['From', 'To']
df = df.join(temp)
df = df.drop('From_To', axis=1)
df
  1. From, To 大小写统一首字母大写其余小写
df['From'] = df['From'].str.capitalize()
df['To'] = df['To'].str.capitalize()
df
  1. Airline 列,有一些多余的标点符号,需要提取出正确的航司名称。举例:'(British Airways. )' 应该改为 'British Airways'.
df['Airline'] = df['Airline'].str.extract('([a-zA-Z\s]+)', expand=False).str.strip()
df
  1. Airline
    delay_1, delay_2, ...
    NAN
    
delays = df['RecentDelays'].apply(pd.Series)
delays.columns = ['delay_{}'.format(n) for n in range(1, len(delays.columns)+1)]
df = df.drop('RecentDelays', axis=1).join(delays)
df

层次化索引

  1. letters = ['A', 'B', 'C']numbers = list(range(10)) 的组合作为系列随机值的层次化索引
letters = ['A', 'B', 'C']
numbers = list(range(4))

mi = pd.MultiIndex.from_product([letters, numbers])
s = pd.Series(np.random.rand(12), index=mi)
s
  1. 检查 s 是否是字典顺序排序的
s.index.is_lexsorted()
# 方法二
# s.index.lexsort_depth == s.index.nlevels
  1. 选择二级索引为 1, 3 的行
s.loc[:, [1, 3]]
  1. s 进行切片操作,取一级索引至 B ,二级索引从 2 开始到最后
s.loc[pd.IndexSlice[:'B', 2:]]
# 方法二
# s.loc[slice(None, 'B'), slice(2, None)]

46.计算每个一级索引的和( A, B, C 每一个的和)

s.sum(level=0)
#方法二
#s.unstack().sum(axis=0)
  1. 交换索引等级,新的Series是字典顺序吗?不是的话请排序

new_s = s.swaplevel(0, 1)
print(new_s)
print(new_s.index.is_lexsorted())
new_s = new_s.sort_index()
print(new_s)

可视化

import matplotlib.pyplot as plt
df = pd.DataFrame({"xs":[1,5,2,8,1], "ys":[4,2,1,9,6]})
plt.style.use('ggplot')
  1. 画出 df 的散点图
df.plot.scatter("xs", "ys", color = "black", marker = "x")
  1. 可视化指定4维DataFrame

df = pd.DataFrame({"productivity":[5,2,3,1,4,5,6,7,8,3,4,8,9],
                   "hours_in"    :[1,9,6,5,3,9,2,9,1,7,4,2,2],
                   "happiness"   :[2,1,3,2,3,1,2,3,1,2,2,1,3],
                   "caffienated" :[0,0,1,1,0,0,0,0,1,1,0,1,0]})

df.plot.scatter("hours_in", "productivity", s = df.happiness * 100, c = df.caffienated)
  1. 在同一个图中可视化2组数据,共用X轴,但y轴不同

df = pd.DataFrame({"revenue":[57,68,63,71,72,90,80,62,59,51,47,52],
                   "advertising":[2.1,1.9,2.7,3.0,3.6,3.2,2.7,2.4,1.8,1.6,1.3,1.9],
                   "month":range(12)})

ax = df.plot.bar("month", "revenue", color = "green")
df.plot.line("month", "advertising", secondary_y = True, ax = ax)
ax.set_xlim((-1,12));

精彩回顾

Python网络爬虫与文本数据分析

如何使用Python快速构建领域内情感词典

中文文本数据逻辑性分析库

中文文本分析相关资源汇总

cnsenti中文情绪情感分析库

Python全栈-60天精通之路

Python数据分析相关学习资源汇总帖

漂亮~pandas可以无缝衔接Bokeh

综述:文本分析在市场营销研究中的应用

2020年B站跨年晚会弹幕内容分析

YelpDaset: 酒店管理类数据集10+G

Loughran&McDonald金融文本情感分析库


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK