python - 如何使用 pandas 分配方法优化数据预处理
问题描述
使用熊猫 1.1.4
从Matt Harrison 的精彩演讲中,我学会了通过链接方法来预处理数据帧,这对我来说似乎很容易阅读。
在尝试使用链接时,我遇到了一些似乎多余的行。
这是MRE:
df = pd.DataFrame({"st_date":[20210915, 20210914, 20211014, 20211010, 20211014],
"language":["python", "python", "python", "java", "java"],
"income":[10000, 12000, 11000, 9000, 8000],
"next_raise":[2000,4000,3000,2000,1000],
"A":[1,2,3,4,5],
"B":[3,4,6,7,1]})
def is_weekday(x):
"""1 = weekday"""
if x <= 4:
return 1
else:
return 0
通常我会通过以下方式进行预处理:
df["st_date"] = pd.to_datetime(df["st_date"], format='%Y%m%d')
df["dayofweek"] = df["st_date"].dt.dayofweek.astype("int8")
df["weekday"] = df["st_date"].dt.dayofweek.apply(is_weekday).astype(np.int8)
df["raise(%)"] = df["next_raise"] / df["income"] * 100
mean_raise = df["raise(%)"].mean()
df["raise_above_mean"] = np.where(df["raise(%)"] > mean_raise, 1, 0)
df.drop(columns=["A", "B"], inplace=True)
df[["income", "next_raise"]] = df[["income", "next_raise"]].astype("int16")
链接上述方法变为:
def preprocess(df):
return (df.assign(dayofweek = df["st_date"].dt.dayofweek.astype("int8"),
weekday = df["st_date"].dt.dayofweek.apply(is_weekday).astype(np.int8),
raise_p = df["next_raise"] / df["income"] * 100,
raise_above_mean = np.where((df["next_raise"] / df["income"] * 100) > #2
(df["next_raise"] / df["income"] * 100).mean(), 1, 0)
)
.astype({"income":"int16",
"next_raise":"int16"})
.drop(columns=["A", "B"])
)
df["st_date"] = pd.to_datetime(df["st_date"], format='%Y%m%d') #1
new_df = preprocess(df)
以下是对我来说似乎多余的行,因此希望使其更有效率。
#1 我想将“st_date”转换为链内的日期时间,当我尝试它时,它似乎在使用之前没有应用,.dt.dayofweek
因此输出AttributeError: Can only use .dt accessor with datetimelike values
#2我计算了两次“提高百分比(raise_p)”(3个,包括上面的一个),我该如何避免这种情况?
最后,很高兴知道你们喜欢什么(包括原因):上面的链接或方法。此外,如果您知道更深入地解释使用链接进行预处理的来源,请告诉我!
解决方案
您可以将值转换为 中的日期时间assign
,但随后需要lambda
使用转换列进行处理的函数。同样forweekday
是不需要自定义功能,比较Series.le
小于或等于。last forraise_above_mean
也是必要的lamba
功能,因为处理计数列:
def preprocess(df):
return (df.assign(st_date = pd.to_datetime(df["st_date"], format='%Y%m%d'),
dayofweek = lambda x: x["st_date"].dt.dayofweek.astype("int8"),
weekday = lambda x: x["st_date"].dt.dayofweek.le(4).astype(np.int8),
raise_p = df["next_raise"] / df["income"] * 100,
raise_above_mean = lambda x: np.where(x["raise_p"] > x["raise_p"].mean(), 1, 0)
)
.astype({"income":"int16",
"next_raise":"int16"})
.drop(columns=["A", "B"])
)
推荐阅读
- c# - 遍历 ViewModel 列表
- c++ - Qt:覆盖/忽略 2 个同名但名称空间不同的类的配方和多个定义
- python - 如何将 Python 变量传递给 XPath 表达式?
- excel - VBA使用自动过滤器将值复制到另一个工作表
- javascript - 如何使用图表 js 在一个图形中创建具有动态 x 和 y 轴的多折线图?
- python - DialogFlow:如何在使用 dialogflow python API 时自动添加参数
- amazon-web-services - 如何将 Amazon Route 53 连接到具有不同服务路由的 VPC 子网?
- google-apps-script - 如何在 Google 表格中的两个给定日期之间自动填充日期
- c - 这个函数的时间和空间复杂度是多少
- android - Flutter - 添加 import 'package:path/path.dart' 时出现错误