pandas
pandas相关
pandas最常用的操作:索引、过滤、数据增删查改、分组聚合数据清理、合并、数据可视化
pandas常见命令操作
1. dataframe筛选
若需要从dataframe中的特定列筛选出特定值所在的行,其中特定列的数量是不确定的,每个特定列的特定值也是不同的,该如何处理?
import pandas as pd
# 创建示例数据
data = {"A": [1, 2, 3, 4],
"B": [5, 6, 7, 8],
"C": [2, 2, 7, 8],
"D": [2, 6, 7, 2]}
df = pd.DataFrame(data)
# 为不同列定义特定值
specific_values = {"A": 2, "B": 6, "C": 2, "D": 6}
# 初始化筛选条件
filter_condition = pd.Series(True, index=df.index)
# 根据每列的要求分别处理
for col, value in specific_values.items():
filter_condition = filter_condition & (df[col] == value)
# 应用筛选条件
filtered_df = df[filter_condition]
print(filtered_df)
## 方法2,使用query
# 构造查询条件
query_string = " & ".join([f"{col} == {val}" for col, val in specific_values.items()])
# 使用query进行筛选
filter_df = df.query(query_string)
总结:
query()
方法适合快速筛选,对于简单的列值筛选,它的性能很好。
np.all()
是一个非常高效的方法,适用于需要筛选多个列的情况,通常比apply()
等方法快。
apply()
方法适合于更加复杂的条件筛选,但它的性能较低,适合在不太关注性能的情况下使用。
isin()
方法在处理多个可选值时非常有效,但它不适用于范围比较的情况。
dataframe 筛选出排除特定几行的数据
2. 在dict中根据value找key
def find_keys_by_value(d, value):
keys = [key for key, val in d.items() if val == value]
return keys
3. 如何根据dataframe的groupby层级关系,生成树。【可以使用图数据库,后续探索一下】
若这个dataframe有两列值呢 ,value1 和value2,其余列不变
import pandas as pd
# 示例 DataFrame
data = {
"Level1": ["A", "A", "A", "B", "B", "C"],
"Level2": ["X", "Y", "Y", "Z", "Z", "X"],
"Level3": ["M", "N", "O", "P", "Q", "R"],
"Value1": [1, 2, 3, 4, 5, 6],
"Value2": [10, 20, 30, 40, 50, 60]
}
df = pd.DataFrame(data)
# 定义构建树的递归函数
def build_tree(df, group_cols, value_cols):
if len(group_cols) == 0:
return df[value_cols].to_dict("records")
current_col = group_cols[0]
grouped = df.groupby(current_col)
tree = {}
for name, group in grouped:
tree[name] = build_tree(group, group_cols[1:], value_cols)
return tree
# 构建树
group_cols = ["Level1", "Level2", "Level3"]
value_cols = ["Value1", "Value2"]
tree = build_tree(df, group_cols, value_cols)
4. dataframe中,特定的两列按照某个函数的计算规则,将所有行计算一遍,生成新的数,存在dataframe的新列中。
import pandas as pd
# Create an example DataFrame
data = {"A": [10, 20, 30, 40],
"B": [2, 4, 6, 8]}
df = pd.DataFrame(data)
# Define a custom function to apply to the two columns
def custom_function(x, y):
return x + y * 2 # Example function: add column A with twice the value of column B
# Apply the custom function to the two columns and create a new column "C"
df["C"] = df.apply(lambda row: custom_function(row["A"], row["B"]), axis=1)
# Display the updated DataFrame
print(df)
方法 | 适用对象 | 作用范围 | 示例 |
---|---|---|---|
apply |
DataFrame / Series | 对列、行或元素应用函数 | 对每列或每行应用函数 axis=0 或 默认值:对每列操作。 axis=1:对每行操作 |
applymap |
DataFrame | 对 DataFrame 每个元素应用函数 | 对 DataFrame 中每个元素应用函数 |
map |
Series | 对 Series 的每个元素应用函数 | 替换或映射 Series 中的每个元素 |
transform |
DataFrame / Series | 对 Series 或 DataFrame 应用元素级转换 | 对 Series 或 DataFrame 中的每个元素进行转换,通常保持原数据形状 |
5. pd.ExcelWriter
将多个dataframe写入EXcel文件的不同sheet
6. 数据切片
data.iloc[1:10,2:4]#前面是行,后面是列
有如下形式的切片
cols = list(range(7, 103)) + list(range(107, data.shape[1]))
data.iloc[4:-1, cols]
7. df去重
去重函数
import pandas as pd
dict={"x":[1,2,3,6],"y":[1,4,1,1],"z":[1,2,4,1]}
df=pd.DataFrame(dict)
## subset可以指定重复的列,进行去重
df.drop_duplicates(subset=["y","z"],keep="first",inplace=True)
8. 按照时间排序
weekofyear_sum中"year"列确实存在重复的值以便触发第二列 "weekofyear"的排序
data_group[i][1].sort_values(by="data_date")
# 同时对两列值排序 True是升序
weekofyear_sum.sort_values(by=["year", "weekofyear"], ascending=[True, True], inplace=True)
9. shift函数
实现对每一天中的相邻行批次号不同的个数的聚合,并且最后得到整段时间内的平均每天相邻行批次号不同的个数
import pandas as pd
# 示例数据
data = {
"datetime_column": pd.to_datetime(["2025-03-20", "2025-03-20", "2025-03-21", "2025-03-21", "2025-03-22"]),
"工序名称": ["A", "A", "B", "B", "A"],
"工序代码": [101, 101, 102, 102, 101],
"工单ID": [1001, 1002, 1003, 1004, 1005],
"批次号": ["B123", "B123", "B456", "B456", "B123"],
"物资编码": ["M001", "M002", "M003", "M004", "M005"],
"过数智能单元": ["X", "X", "Y", "Y", "X"]
}
# 创建 DataFrame
df = pd.DataFrame(data)
# 定义 sub_select 函数进行按日期分组聚合
def sub_select(df):
# 按日期分组
df["日期"] = df["datetime_column"].dt.date # 提取日期部分(去掉时间)
# 计算每一天中相邻行批次号不同的个数
df["批次号不同"] = (df["批次号"] != df["批次号"].shift()).astype(int)
# 按日期分组并计算每一天批次号不同的个数
daily_diff_counts = df.groupby("日期")["批次号不同"].sum()
# 计算所有天的平均批次号不同的个数
average_daily_diff = daily_diff_counts.mean()
return average_daily_diff
# 计算分组后的结果
result = df.groupby(["工序名称", "工序代码", "过数智能单元"]).apply(sub_select)
# 打印结果
print(result)
10. 筛选
10.1. 某一列中特定值进行筛选
# 筛选出某列是特定值的行
data[data["target"] == "taget1"]
# 筛选出某列是特定值的行,此特定值包含多种情况
lines = ["a", "b", "c"]
data = data[data["sku_id"].isin(lines)]
10.2. 某多列中特定值进行筛选
import pandas as pd
# 新建dataframe
df1 = pd.DataFrame{{
"A":[25, 30, 35, 40],
"B":["A", "B", "C", "D],
"C":["X", "Y", "Z", "W"],
"D":[1, 2, 3, 4]
}}
filter_series = pd.Series{{
"C": 30,
"B": "A"
}}
#映射字典
column_mapping = {
"C" : "A",
}
filter_df = df1[df1.apply(lambda row: all(row[column_mapping.get(col, col)] == val for col, val in filter_series.item()), axis = 1)]
11. 排序
12. 分组
# 按某一列分组
after_gb = df.groupby("col_name")
分组之后可以将group类型转为list类型进行查看
after_gb_list = list(after_gb)
list之后的数据结构是元组形式,元组中包含col_name也包含dataframe
for name, data in after_df:
print(name)
print(data) # 遍历出来的data是dataframe的数据格式
after_df.sum() # 分组之后的聚合操作
after_df.mean() # 分组
after_df["col_name"].transform("sum") # 将求和结果分到每一行上,返回series
过滤:删除某些行
例如:
after_df.filter(lambda x: x["销量"].sum() > 6)
13. 拼接
拼接用法
官方文档指南
dataframe的拼接有四个函数可以使用,分别是merge、join、concat、compare,其中文含义分别是合并、连接、串联、对比。
13.1. concatenate-串联(concat函数)
concat函数中axis的用法
concat函数参数介绍及用法代码示例
concat默认是按轴拼接,轴的意思是行index。即默认参数axis = 0。
# concat函数(上下拼接)
df = pd.concat(objs, axis = 0, ignore_index = False, join = "outer")
# objs: 指的是要合并的dataframe(们)。可以是一个列表[df1,df2,...]也可以是一个集合(df1,df2,...)
# axis:dataframe拼接的方向。默认axis=0,上下拼接;设置axis=1,左右拼接
# ignore_index:是否需要重新设置索引,默认是False
# join:默认join = "outer",非交集用nan填。若join = "inner",显示交集
两个单列dataframe想进行上下拼接,并拼接成单列时,需要注意列名必须一样。
s1 = pd.Series(["a", "b", "c"], index=[0, 1, 2])
s2 = pd.Series(["d", "e", "f"], index=[0, 1, 2])
s1df = s1.to_frame(name="值")
s2df = s2.to_frame(name="值3")
s12 = pd.concat([s1df, s2df])
print(s12)
# 值 值3
# 0 a NaN
# 1 b NaN
# 2 c NaN
# 0 NaN d
# 1 NaN e
# 2 NaN f
# 创建两个示例 DataFrame,包含相同的列名
df1 = pd.DataFrame({
"A": [1, 2, 3],
"B": [4, 5, 6]
})
df2 = pd.DataFrame({
"A": [7, 8, 9],
"B": [10, 11, 12]
})
# 使用 pd.concat 进行横向拼接
result = pd.concat([df1, df2], axis=1)
# 打印结果
print(result)
# A B A B
#0 1 4 7 10
#1 2 5 8 11
#2 3 6 9 12
13.2. merge
pandas.DataFrame.merge() 参数详解
是使用数据库风格的连接合并DataFrame或已命名的系列对象
DataFrame.merge(left, right, how="inner", on=None, left_on=None, right_on=None,
left_index=False, right_index=False, sort=False, suffixes=("_x", "_y"),
copy=True, indicator=False, validate=None)
# 关键参数为left_df,right_df、how、on
# how有 {‘left’, ‘right’, ‘outer’, ‘inner’}, default ‘inner’ 默认为合并两个frame的交集
# on表示连接时,参考的主键。可以是一个,也可以是多个。
如果基于两边的索引合并,使用 left_index=True 和 right_index=True
13.3. 左连接时,发现左边表格行数变多,是什么原因导致的。
右边表格有重复的行: 在左连接中,左表的每一行会与右表中满足连接条件的行进行匹配。如果右表中某个值出现了多次,那么左表中相应的每一行都会与右表中的每一匹配行进行组合,从而导致左表的行数增加。
-
右边表格有重复的行:
例如:
- 左表(A):
ID Name 1 Tom 2 Jerry - 右表(B):
ID Score 1 90 1 85 2 88
当你对这两个表进行左连接时,左表的行数会增加,因为 ID 为 1 的行在右表中有两条记录,结果如下:
ID Name Score 1 Tom 90 1 Tom 85 2 Jerry 88 这里,ID 为 1 的行出现了两次。
- 左表(A):
解决办法:
- 可以通过检查右表是否有重复行来避免这一问题,或者使用
DISTINCT
语句来去除重复项。 - 如果不希望某些行重复,可以通过调整连接条件或使用合适的聚合函数来控制重复数据。
14. dataframe转ndarray、ndarray转dataframe
df.values
pd.dataframe(ndarray)
15. 增加多列
pandas dataframe 新增单列和多列
df[["column_new_1", "column_new_2", "column_new_3"]] = pd.DataFrame([[np.nan, "dogs", 3]], index=df.index)
16. 修改列名
pandas DataFrame数据重命名列名的几种方式
16.1. 删除指定行
obj_cols = ["data_date", "destination_country", "service_level_name", "goods_type_name"]
df_dropped = i_df_T.drop(index=obj_cols) # 删除行名为obj_cols的行
17. 输出为excel
import pandas as pd
# 创建一个示例 DataFrame
data = {"A": [1, 2, 3], "B": [4, 5, 6]}
df = pd.DataFrame(data)
# 输出为 Excel 文件,不包含索引
df.to_excel("df.xlsx", index=False)
原文地址:https://www.cnblogs.com/systemTang/p/18949023