游戏角色自定义系统架构与Unity实现全解析
2026/7/10 9:34:50
欢迎来到第49天!
在现实世界中,我们拿到的数据从来都不是完美的。它们可能:
NaN)。数据分析师 80% 的时间都在做数据清洗 (Data Cleaning)。只有把数据洗干净了,后续的分析和模型才有意义(Garbage In, Garbage Out)。
本节内容:
isnull,dropna,fillna)duplicated,drop_duplicates)astype)merge)concat)在 Pandas 中,缺失值通常显示为NaN(Not a Number) 或None。
importpandasaspdimportnumpyasnp# 创建一个包含缺失值的 DataFramedf=pd.DataFrame({"Name":["Tom","Jerry","Spike",None],"Score":[88,np.nan,75,60],"City":["Beijing","Shanghai",np.nan,"Beijing"]})print(df)print(df.isnull())# 返回布尔表 (True 表示缺失)print(df.isnull().sum())# 统计每列缺失值的数量 (非常常用!)# Name 1# Score 1# City 1# 只要有一列是 NaN,整行删除df_clean=df.dropna()# 只有全行都是 NaN 才删除df_clean_all=df.dropna(how='all')# 删除 Score 列缺失的行 (subset 指定列)df_score_clean=df.dropna(subset=['Score'])删除太可惜了,我们通常会用默认值或平均值填充。
# 1. 用固定值填充 (所有 NaN 变 0)df_filled=df.fillna(0)# 2. 用字典针对不同列填充values={"Name":"Unknown","Score":df["Score"].mean(),"City":"Unknown"}df_filled_smart=df.fillna(value=values)print(df_filled_smart)data={"Name":["Tom","Tom","Jerry"],"Age":[10,10,8]}df=pd.DataFrame(data)# 1. 检查重复 (返回布尔 Series)print(df.duplicated())# 2. 删除重复 (保留第一条)df_unique=df.drop_duplicates()print(df_unique)经常遇到读进来的数字是字符串类型(比如 “100”),这会导致无法计算。
df=pd.DataFrame({"Price":["100","200","300"]})# 查看类型print(df.dtypes)# Price object (即字符串)# 转换类型 (astype)df["Price"]=df["Price"].astype(int)print(df.dtypes)# Price int32这是 SQL 用户最熟悉的操作。
根据某一列(键)将两张表左右拼接。
# 用户表df_users=pd.DataFrame({"user_id":[1,2,3],"name":["Alice","Bob","Charlie"]})# 订单表df_orders=pd.DataFrame({"order_id":[101,102,103],"user_id":[1,1,2],# user_id 是外键"amount":[50,100,200]})# 内连接 (Inner Join): 只保留两边都有的merged=pd.merge(df_orders,df_users,on="user_id",how="inner")print(merged)# order_id user_id amount name# 0 101 1 50 Alice# 1 102 1 100 Alice# 2 103 2 200 Bob# (注意:Charlie 没有订单,所以不在结果里)# 左连接 (Left Join): 保留左表所有数据merged_left=pd.merge(df_orders,df_users,on="user_id",how="left")简单的上下堆叠(增加行)。
df1=pd.DataFrame({"A":[1,2]})df2=pd.DataFrame({"A":[3,4]})# 上下拼接 (axis=0)result=pd.concat([df1,df2],ignore_index=True)print(result)# A# 0 1# 1 2# 2 3# 3 4假设我们有一份脏数据raw_data.csv:
id,product,price,sales 1,Apple,5.0,100 2,Banana,3.5, 3,Apple,5.0,100 4,Orange,,50 5,Grape,10.0,20任务:
sales(用 0 填充)。price缺失的行。importpandasaspdfromioimportStringIO# 模拟读取 CSV (为了方便演示,直接用字符串)csv_data="""id,product,price,sales 1,Apple,5.0,100 2,Banana,3.5, 3,Apple,5.0,100 4,Orange,,50 5,Grape,10.0,20 """df=pd.read_csv(StringIO(csv_data))print("---"" 原始数据 ---"")print(df)# 1. 去重 (排除 id 列,只看内容是否重复)# keep='first': 保留第一个df=df.drop_duplicates(subset=['product','price','sales'])# 2. 填充 sales (NaN -> 0)df['sales']=df['sales'].fillna(0)# 3. 删除 price 缺失的行df=df.dropna(subset=['price'])# 4. 计算销售额# 确保类型正确 (以防万一)df['price']=df['price'].astype(float)df['sales']=df['sales'].astype(int)df['revenue']=df['price']*df['sales']print("\n---"" 清洗后数据 ---"")print(df)print(f"\n总销售额:{df['revenue'].sum()}")fillna(inplace=True)是什么意思?很多 Pandas 方法(如fillna,drop)默认不会修改原数据,而是返回一个新的 DataFrame。
df = df.fillna(0)(推荐,逻辑清晰)df.fillna(0, inplace=True)(直接修改 df,不返回)merge时列名不一样怎么办?如果是左表的uid和右表的user_id连接:
pd.merge(df_left,df_right,left_on="uid",right_on="user_id")关键要点:
df.info()和df.isnull().sum()。dropna)、填(fillna)、插值。merge,一定要搞清是 Inner 还是 Left Join。["Name", "Age", "Email"]。math.csv(学号, 数学分) 和english.csv(学号, 英语分)。请读取并用merge将它们合并成一张总表 (学号, 数学, 英语)。Day 50:数据可视化 Matplotlib 基础- 数据洗干净了,终于可以画图了!明天我们系统学习 Matplotlib,绘制折线图、散点图和饼图。
系列导航: