1、Series.value_counts(normalize=False)与Series.count()
- value_counts(normalize=False): 统计df某一列各个值出现的次数,若noemalize=True,则返回出现频率
- count():返回某一列非空元素的个数
2、修改df的数据类型
- 在创建df时指定数据类型
data = {"a" :[1,2,3], "b":[4,5,6]}
data = pd.DataFrame(data, dtype={"a": np.float, "b": np.int}) # 这种写法错误,dtype只允许指定单个类型,如果不指定dtype,则自动推断得出
data = pd.DataFrame(data, dtype=np.float)
- 在read_csv时,指定数据类型
data = pd.read_csv(filepath, dtype={....}) # 可以是字典
- 转换Series的数据类型
s = pd.Series([1,2,3,4,"a"])
s = pd.to_numeric(s, errors="ignore")
# errors:
"raise" : 遇到不能转化的元素时,将错误抛出
"coerce":遇到不能转化的元素时,将其强制转化为NaN
"ignore":不对不能转化的元素进行转换
- 将df的多列进行数据类型转换
df[["col1", "col2"]] = df[["col1", "col2"]].apply(pd.to_numeric)
- 将df的多列进行强制数据类型转换
df[["col1", "col2"]] = df[["col1", "col2"]].astype(float)
3、修改df的列名
df.rename(columns={o1 : n1, o2:n2, o3:n3,...}, inplace=True)
4、将Series转化为Dateframe
s = s.to_frame()
5、删除df满足条件的某一列或多列,删除含有nan的行或列
del df["col1"] # 删除一列
df.drop(columns = df.columns[[0,1,2]], inplace=True) #刪除df前3列
df.dropna(how="any", axis=1, inplace=True) # 刪除包含nan的列
df.dropna(how="any", axis=0, inplace=True) # 刪除包含nan的行
df.dropna(subset=[列名], inplace=True) # 删除某列为空的行
df.drop(data[布尔条件表达式])
6、pandas画时间序列图并且调整横坐标的显示
"""
坐标轴为时间序列
"""
fig, ax = plt.subplots(1, 1, figsize=(15, 8))
ax.scatter(data.index, data["wrist_temp"], s=8, label="wrist_temp")
ax.scatter(data.index, data["bottom_temp"], s=8, label="bottom_temp")
ax.scatter(data.index, data["env_temp"], s=8, label="env_temp")
# 设置x轴刻度
ax.set_xlim((start_time - pd.Timedelta("30min"), end_time + pd.Timedelta("30min")))
ax.set_xticks(pd.date_range(start_time-pd.Timedelta("30min"), end_time+pd.Timedelta("30min"), freq="30min"))
ax.set_xticklabels(pd.date_range(start_time-pd.Timedelta("30min"), end_time+pd.Timedelta("30min"),
freq="30min").astype("str"), rotation=90, fontdict={"size": 12})
from matplotlib import dates
ax.xaxis.set_major_formatter(dates.DateFormatter("%m-%d %H:%M")) # 设置x轴时间标签显示格式 !!
# 设置y轴刻度
ax.set_ylim((25, 38))
ax.set_yticks(np.arange(25, 39, 1))
ax.set_yticklabels(np.arange(25, 39, 1), fontdict={"size": 12})
ax.set_title(f.split(".")[0])
ax.legend(loc="best", prop={"family": "SimHei", "size": 15})
ax.grid(which='major', c='lightgrey', linewidth="1", axis="y")
plt.savefig("./figures/" + f.split(".")[0] + ".png", dpi=600, bbox_inches="tight") # 解决输出图像不清晰及不完整的问题
plt.show()
7、将两个dataframe按照某一列进行就近连接
from functools import reduce
final_data1 = reduce(lambda left, right: pd.merge_asof(left, right, on="time", direction="nearest", tolerance=pd.Timedelta("20s")), merge_data1)
final_data1.dropna(axis=1, inplace=True, how="all")
input:
date_start_time employee_id session_id
0 2016-01-01 02:03:00 7261824 871631182
1 2016-01-01 06:03:00 7261824 871631183
2 2016-01-01 11:01:00 7261824 871631184
3 2016-01-01 14:01:00 7261824 871631185
date_start_time employee_id session_id
0 2016-01-01 02:03:00 7261824 871631182
1 2016-01-01 06:05:00 7261824 871631183
2 2016-01-01 11:04:00 7261824 871631184
3 2016-01-01 14:10:00 7261824 871631185
tol = pd.Timedelta('5 minute')
d = pd.merge_asof(left=df1,right=df2, on="date_start_time", direction='nearest',tolerance=tol)
"""
param direction:
backward: 对于df1中的每一行x1,在df2 "on"指定的列中寻找比x1[on]小的最后一行进行拼接
forward: 对于df1中的每一行x1,在df2 "on"指定的列中寻找比x1[on]大的第一行进行拼接
nearest: 对于df1中的每一行x1,在df2 "on"指定的列中寻找离x1[on]最近的一行进行拼接
"""
output:
date_start_time employee_id_x session_id_x employee_id_y session_id_y
0 2016-01-01 02:03:00 7261824 871631182 7261824.0 871631182.0
1 2016-01-01 06:03:00 7261824 871631183 7261824.0 871631183.0
2 2016-01-01 11:01:00 7261824 871631184 7261824.0 871631184.0
3 2016-01-01 14:01:00 7261824 871631185 NaN NaN
8、dataframe按指定列排序
df.sort_values(by="sales" , ascending=False)
9、DataFrame对象的分组操作
DataFrame分组操作主要用到3个函数:groupby,pd.Grouper(),agg
- groupby返回的是一个DataFrameGroupBy结构,这个结构必须调用聚合函数(如sum)之后,才会得到结构为Series的数据结果。而agg是DataFrame的直接方法,返回的也是一个DataFrame。当然,很多功能用sum、mean等等也可以实现。但是agg更加简洁, 而且传给它的函数可以是字符串,也可以自定义。
- pd.Grouper使用户能够为时间列指定处理方式
pd.Grouper(key=None, level=None, freq=None, axis=0, sort=False)
- key:用来指定 groupby 所作用目标数据的分组列(某些列特征),默认为 None。
- level:目标索引的级别。名称/数字,默认无。# 暂时没用到这个参数
- freq:如果目标列(通过 key 或 level )选择是类似日期时间的对象,则将按指定的频率进行分组。
- axis:轴的编号,1 为列,默认值 0 为行。
- sort:是否对生成的标签进行排序。默认为 False。
完整的freq规格:
https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases
一个例子:
将时间数据集按照1小时聚合并对指定列取平均(不包含0值)
def non_zero_mean(array):
new_array = [i for i in array if i!=0]
return round(np.mean(new_array), 1)
res_ = res.groupby(["user_name", "prod_name", pd.Grouper(key='timestamp', freq='1H')])[["bodytemp_continue", "skintemp_continue"]]\
.agg(non_zero_mean)
res_.reset_index(inplace=True)
res_.to_csv("./res_final.csv", index=False, encoding="utf_8_sig")