主要写一些平时看到的比较常用的一些pd的函数的应用,通过应用场景来辅助更好地理解pandas。
合并高度对称的列
在实际运用过程中,我们可能会拿到形如以下形式的数据:
这样的数据集存在几个列的内容完全一致,因此我们希望实现的一个功能就是将这几个列的值合成一个列,得到形如下图的数据形式:
import pandas as pd df = pd.DataFrame({ '爱好1': {'小明': '睡觉', '小红': '弹琴'}, '地点1': {'小明': '床上', '小红': '家'}, '爱好2': { '小明': '骑马', '小红': '开车' }, '地点2': { '小明': '马场', '小红': '车上' } }) df df[['爱好1', '地点1']].append(df[['爱好2', '地点2']].rename( columns={'爱好2': '爱好1', '地点2': '地点1'})) df['爱好'] = df[['爱好1', '爱好2']].agg(tuple, axis=1) df['地点'] = df[['地点1', '地点2']].agg(tuple, axis=1) df['爱好-地点'] = df['爱好'].combine(df['地点'], func=lambda x, y: list(zip(x, y)))
df = df.filter(regex=r'(?<!\d)$') df = df.explode('爱好-地点') df[['爱好', '地点']] = df['爱好-地点'].apply(pd.Series) df df = pd.DataFrame({ '爱好1': {'小明': '睡觉', '小红': '弹琴'}, '地点1': {'小明': '床上', '小红': '家'}, '爱好2': { '小明': '骑马', '小红': '开车' }, '地点2': { '小明': '马场', '小红': '车上' } }) pd.lreshape(df, {'爱好': ['爱好1', '爱好2'], '地点': ['地点1', '地点2'] })
|
第二种方法相对来说比较繁琐一些,但是也帮助我们更好地去理解pd的聚合函数。
apply函数的灵活运用
- 计算分位数
frame = pd.DataFrame({'data1': np.random.randn(1000), 'data2': np.random.randn(1000)}) quartiles = pd.cut(frame.data1, 4) quartiles[:10] def get_stats(group): return {'min': group.min(), 'max': group.max(), 'count': group.count(), 'mean': group.mean()} grouped = frame.data2.groupby(quartiles) grouped.apply(get_stats).unstack()
grouping = pd.qcut(frame.data1, 10, labels=False) grouped = frame.data2.groupby(grouping) grouped.apply(get_stats).unstack()
|
- 插补缺失值
states = ['Ohio', 'New York', 'Vermont', 'Florida', 'Oregon', 'Nevada', 'California', 'Idaho'] group_key = ['East'] * 4 + ['West'] * 4 data = pd.Series(np.random.randn(8), index=states) data data[['Vermont', 'Nevada', 'Idaho']] = np.nan data data.groupby(group_key).mean() fill_mean = lambda g: g.fillna(g.mean()) data.groupby(group_key).apply(fill_mean) fill_values = {'East': 0.5, 'West': -1} fill_func = lambda g: g.fillna(fill_values[g.name]) data.groupby(group_key).apply(fill_func)
|
- 制作扑克牌
suits = ['H', 'S', 'C', 'D'] card_val = (list(range(1, 11)) + [10] * 3) * 4 base_names = ['A'] + list(range(2, 11)) + ['J', 'K', 'Q'] cards = [] for suit in ['H', 'S', 'C', 'D']: cards.extend(str(num) + suit for num in base_names)
deck = pd.Series(card_val, index=cards) deck[:13] def draw(deck, n=5): return deck.sample(n) draw(deck) get_suit = lambda card: card[-1] deck.groupby(get_suit).apply(draw, n=2)
|
找出最邻近时间点所在行
考虑有一个电影上映时间的数据库,希望查找到最近要上映的所有电影,如果是只找出一个电影,用idxmin()
函数很容易解决,不过需要注意应先从数据库中取出所有上映时间在当前时间之后的电影,然后再使用idxmin()
函数。如果想要取出所有电影,这里提供一个比较粗糙的思路:
df=df.loc[df['上映时间']>time] df.loc[df['上映时间']-time==max(df['上映时间']-time)]
|