原理
导包:
from itertools import groupby
其实groupby就是对可迭代对象的批量操作。(可迭代对象就是像list、dict、迭代器等这种可以用for循环遍历的数据结构或者对象)
groupby()的作用就是把可迭代对象中相邻的重复元素挑出来放一起,举个例子:
for key, group in groupby('AAABBBCCAAA'):
print(key, list(group))
输出:
A ['A', 'A', 'A']
B ['B', 'B', 'B']
C ['C', 'C']
A ['A', 'A', 'A']
其中变量key表示的是重复元素,group是一个itertools._grouper类型的变量,也是个迭代对象,'''list(group)'''表示的是将迭代对象转化为列表。
具体原理如下图所示:
实际上挑选规则是通过函数完成的,只要作用于函数的两个元素返回的值相等,这两个元素就被认为是在一组的,而函数返回值作为组的key。如果我们要忽略大小写分组,就可以让元素'A'和'a'都返回相同的key:
for key, group in groupby('AaaBBbcCAAa', lambda c: c.upper()):
print(key, list(group))
具体原理如下图所示:
骚操作
有这么一个情形,我要处理pandas.DataFrame表格数据,如下图所示,value这一列有很多连续的空值,空值处理需求如下:
- 连续空值行数超过10次的行全部按行删掉;
- 连续空值行数小于等于10次的,则取上一个实数值和下一个实数值的均值来补全。
试问应该怎么做?
答案:
NUM_NAN = 10
nan_r, _ = np.where(np.isnan(df)) # 找到所有NaN的值位置,nan_r表示行标,占位符_表示列标
# 统计哪一块数据应该删除
nan_list = [] # 只收集连续空值超过NUM_NAN个数的行索引
fun = lambda x: x[1] - x[0]
for k, g in groupby(enumerate(nan_r), fun):
find_list = [j for i, j in g] # 连续数字的列表
if len(find_list) > NUM_NAN: # 时间连续的点超过NUM_NAN个就删掉
nan_list = nan_list + find_list
# 存较大片的缺省值,进行删除
if len(nan_list) != 0:
df = df.reset_index()
df = df.drop(nan_list)
df = df.set_index(df['time'])
df = df.drop(['time'], axis=1)
# 缺省值取前一行和后一行的均值
df = (df.fillna(method='backfill') + df.fillna(method='pad')) / 2
df.to_csv('test.csv')