Pandas数据分析入门:从核心数据结构到实战应用 在数据处理和分析的日常工作中你是否曾为Excel表格的繁琐操作而烦恼是否在面对海量数据时感到无从下手或者写出的Python脚本效率低下、难以维护如果你有这些困扰那么Pandas将是你的得力助手。作为Python数据分析领域的“瑞士军刀”Pandas以其强大的数据结构和便捷的操作接口已经成为数据科学家、分析师和开发者的必备技能。本文将带你从零开始系统性地掌握Pandas的核心用法通过大量可运行的代码示例让你在短时间内快速入门并能将所学知识应用到实际项目中无论是处理销售数据、进行商业分析还是完成学术研究都能得心应手。1. Pandas是什么为什么你需要它在深入代码之前我们首先要理解Pandas的定位和价值。很多初学者会把它和NumPy、Excel甚至数据库混淆这里需要做一个清晰的界定。Pandas是一个开源的、基于NumPy的Python库它提供了高性能、易用的数据结构和数据分析工具。它的名字来源于“Panel Data”面板数据和“Python Data Analysis”Python数据分析的组合。简单来说Pandas就是专门为处理“表格数据”或“关系型数据”而生的。它解决了什么问题想象一下你需要处理一个包含成千上万行数据的CSV文件进行数据清洗如处理缺失值、重复值、转换如类型转换、计算新列、分析如分组统计、透视表和可视化。如果只用Python原生的列表和字典代码会变得冗长且低效。Pandas将这些操作封装成了简洁、直观的方法让你能用一两行代码完成复杂的数据操作。核心数据结构Series 和 DataFrame这是理解Pandas的基石Series可以看作是一个带标签的一维数组。标签就是索引Index数据可以是任何类型整数、字符串、浮点数等。它类似于Excel中的一列数据。DataFrame这是Pandas中最常用、最重要的数据结构。它是一个二维的、表格型的数据结构既有行索引也有列索引。你可以把它理解为一个Excel工作表或一个SQL数据库表。DataFrame由多个Series组成每一列都是一个Series。常见应用场景数据清洗与预处理处理缺失值、异常值、重复数据进行数据格式标准化。数据探索与分析计算统计指标均值、中位数、标准差、进行分组聚合、生成透视表。数据可视化虽然Pandas本身不负责绘图但它可以完美地与Matplotlib、Seaborn等库集成快速生成图表。数据读写轻松读写CSV、Excel、JSON、SQL数据库、HTML等多种格式的数据。时间序列分析Pandas对时间序列数据有原生支持非常适合处理带有时间戳的数据。掌握Pandas意味着你拥有了高效处理结构化数据的核心能力这是迈向数据分析、机器学习等领域的关键一步。2. 环境准备与安装工欲善其事必先利其器。在开始编写Pandas代码前我们需要搭建好开发环境。1. Python版本建议使用Python 3.7及以上版本。你可以在命令行中输入python --version或python3 --version来检查。2. 安装Pandas安装Pandas非常简单使用Python的包管理工具pip即可。打开你的终端Windows的CMD/PowerShellmacOS/Linux的Terminal并执行以下命令pip install pandas如果你使用的是Anaconda发行版推荐给数据分析初学者因为它集成了众多科学计算库可以使用conda安装conda install pandas3. 推荐集成开发环境IDEJupyter Notebook / JupyterLab非常适合数据分析和探索支持交互式编程和即时可视化是学习Pandas的绝佳工具。可以通过pip install jupyter安装。PyCharm功能强大的专业Python IDE社区版免费。提供了优秀的代码补全、调试和项目管理功能。VS Code轻量级且高度可定制的编辑器通过安装Python插件可以获得媲美IDE的体验。4. 验证安装创建一个新的Python文件例如test_pandas.py或在Jupyter Notebook的一个单元格中输入以下代码并运行import pandas as pd print(fPandas version: {pd.__version__})如果没有报错并成功输出版本号如1.5.3说明安装成功。本文后续所有示例都将基于import pandas as pd这个约定俗成的导入方式。3. Pandas核心数据结构详解理解了Series和DataFrame就掌握了Pandas的一半。让我们通过具体代码来感受它们。3.1 Series带标签的一维数组创建Series最基本的方式是使用一个列表。import pandas as pd # 从一个列表创建Series默认使用从0开始的整数索引 s1 pd.Series([10, 20, 30, 40]) print(s1:) print(s1) print(fs1的类型: {type(s1)}) print(fs1的索引: {s1.index}) print(fs1的值: {s1.values})输出s1: 0 10 1 20 2 30 3 40 dtype: int64 s1的类型: class pandas.core.series.Series s1的索引: RangeIndex(start0, stop4, step1) s1的值: [10 20 30 40]我们可以自定义索引这使得数据访问更加直观。# 创建Series并指定自定义索引 s2 pd.Series([88, 92, 75, 84], index[张三, 李四, 王五, 赵六]) print(\ns2 (带自定义索引):) print(s2) # 通过索引访问数据 print(f李四的成绩: {s2[李四]}) # 也可以通过位置访问iloc print(f第二个同学的成绩按位置: {s2.iloc[1]})3.2 DataFrame二维数据表DataFrame是数据分析的主战场。创建DataFrame的方式多种多样最常用的是从字典创建。# 从一个字典创建DataFrame字典的键将成为列名值列表成为列数据 data { 姓名: [张三, 李四, 王五, 赵六], 年龄: [25, 30, 35, 28], 城市: [北京, 上海, 广州, 深圳], 薪资: [15000, 18000, 12000, 20000] } df pd.DataFrame(data) print(创建的DataFrame df:) print(df) print(f\nDataFrame的形状 (行数, 列数): {df.shape}) print(f列名: {df.columns.tolist()}) print(f索引: {df.index.tolist()})输出创建的DataFrame df: 姓名 年龄 城市 薪资 0 张三 25 北京 15000 1 李四 30 上海 18000 2 王五 35 广州 12000 3 赵六 28 深圳 20000 DataFrame的形状 (行数, 列数): (4, 4) 列名: [姓名, 年龄, 城市, 薪资] 索引: [0, 1, 2, 3]查看数据的基本信息在拿到一个陌生的DataFrame时我们首先需要快速了解其概况。# 查看前n行默认5行 print(前2行数据:) print(df.head(2)) # 查看后n行 print(\n后2行数据:) print(df.tail(2)) # 获取快速统计摘要仅对数值列有效 print(\n数值列的统计信息:) print(df.describe()) # 查看索引、列名、数据类型和非空值数量 print(\nDataFrame信息:) print(df.info())df.info()的输出非常有用它能告诉你每列的数据类型dtype比如object通常是字符串int64是整数float64是浮点数。了解dtype对后续的数据操作至关重要。4. 数据读写与外部世界交互Pandas支持读写多种格式的数据这是连接数据源和数据处理的桥梁。4.1 读取数据从CSV文件读取CSV逗号分隔值是最常见的数据交换格式。# 假设有一个名为 sales_data.csv 的文件 # df_csv pd.read_csv(sales_data.csv) # print(df_csv.head()) # 由于我们没有实际文件这里演示从字符串读取模拟CSV内容 csv_data 日期,产品,销售额,数量 2023-10-01,产品A,1000,50 2023-10-01,产品B,1500,30 2023-10-02,产品A,1200,60 2023-10-02,产品C,800,20 df_from_csv pd.read_csv(pd.compat.StringIO(csv_data)) print(从CSV字符串读取的数据:) print(df_from_csv)read_csv有非常多的参数常用如encoding: 指定编码如‘utf-8’,‘gbk’解决中文乱码。sep/delimiter: 指定分隔符默认是逗号。header: 指定哪一行作为列名默认为0第一行。index_col: 指定哪一列作为行索引。从Excel文件读取需要安装openpyxl或xlrd库。pip install openpyxl# 读取Excel文件 # df_excel pd.read_excel(data.xlsx, sheet_nameSheet1)从字典列表创建常见于API返回的JSON数据json_like_data [ {name: Alice, score: 85}, {name: Bob, score: 92}, {name: Charlie, score: 78} ] df_from_json pd.DataFrame(json_like_data) print(\n从字典列表创建的DataFrame:) print(df_from_json)4.2 写入数据将处理好的数据保存下来同样重要。# 将DataFrame写入CSV文件indexFalse表示不将行索引写入文件 df.to_csv(output_data.csv, indexFalse, encodingutf-8-sig) # utf-8-sig能更好兼容Excel中文 # 将DataFrame写入Excel文件 # df.to_excel(output_data.xlsx, indexFalse, sheet_nameSheet1) print(数据已写入到 output_data.csv)5. 数据查看与选择如何获取你想要的数据数据选择是数据分析中最频繁的操作。Pandas提供了非常灵活且强大的数据索引和选择方法。5.1 选择列选择单列会返回一个Series选择多列则返回一个DataFrame。# 选择单列 - 返回Series ages df[年龄] print(选择‘年龄’列 (Series):) print(ages) print(type(ages)) # 选择多列 - 返回DataFrame subset df[[姓名, 城市]] print(\n选择‘姓名’和‘城市’列 (DataFrame):) print(subset) print(type(subset))5.2 选择行选择行主要使用.iloc基于整数位置和.loc基于标签索引。# 使用 .iloc 按整数位置选择 # 选择第二行索引为1 print(使用iloc选择第二行:) print(df.iloc[1]) # 选择前两行 print(\n使用iloc选择前两行:) print(df.iloc[0:2]) # 切片包含起始不包含结束 # 使用 .loc 按标签选择我们的索引是默认的0,1,2,3所以和iloc在这里效果一样 print(\n使用loc选择索引为1和2的行:) print(df.loc[[1, 2]]) # 更强大的loc可以同时选择行和列 print(\n使用loc选择索引为1的行并只显示‘姓名’和‘薪资’列:) print(df.loc[1, [姓名, 薪资]]) # 返回一个Series print(\n使用loc选择索引0到2的行并只显示‘姓名’和‘城市’列:) print(df.loc[0:2, [姓名, 城市]]) # 注意loc的切片是包含结束位置的5.3 条件筛选布尔索引这是数据查询的核心通过逻辑条件来过滤数据。# 筛选出年龄大于28的员工 older_than_28 df[df[年龄] 28] print(年龄大于28的员工:) print(older_than_28) # 多个条件组合使用 (与), | (或), ~ (非)每个条件必须用括号括起来 high_salary_in_bj df[(df[城市] 北京) (df[薪资] 14000)] print(\n城市为北京且薪资大于14000的员工:) print(high_salary_in_bj) # 使用 isin 进行成员测试 cities_of_interest [上海, 广州] in_specific_cities df[df[城市].isin(cities_of_interest)] print(\n城市在上海或广州的员工:) print(in_specific_cities)6. 数据处理与清洗让数据变得可用原始数据往往存在各种问题清洗是必不可少的一步。6.1 处理缺失值缺失值在Pandas中用NaNNot a Number表示。# 创建一个包含缺失值的DataFrame data_with_na { A: [1, 2, None, 4], B: [5, None, None, 8], C: [10, 11, 12, 13] } df_na pd.DataFrame(data_with_na) print(包含缺失值的原始DataFrame:) print(df_na) # 检查缺失值 print(\n每列的缺失值数量:) print(df_na.isnull().sum()) print(\n整个DataFrame的缺失值情况True表示缺失:) print(df_na.isnull()) # 处理缺失值 # 1. 删除包含缺失值的行 df_dropna df_na.dropna() print(\n删除缺失值后的DataFrame (dropna):) print(df_dropna) # 2. 填充缺失值 df_fillna df_na.fillna({A: df_na[A].mean(), B: 0}) # A列用均值填充B列用0填充 print(\n填充缺失值后的DataFrame (fillna):) print(df_fillna)6.2 处理重复值# 创建有重复行的数据 df_dup pd.DataFrame({ name: [Alice, Bob, Alice, David, Bob], score: [90, 85, 90, 88, 85] }) print(包含重复值的DataFrame:) print(df_dup) # 检查重复行 print(f\n重复行数量: {df_dup.duplicated().sum()}) print(重复行标记:) print(df_duplicated()) # 删除重复行 df_drop_dup df_dup.drop_duplicates() print(\n删除重复行后的DataFrame:) print(df_drop_dup) # 基于特定列删除重复值保留第一个 df_drop_dup_subset df_dup.drop_duplicates(subset[name]) print(\n基于‘name’列删除重复保留第一个:) print(df_drop_dup_subset)6.3 数据类型转换正确的数据类型能提升性能并避免错误。# 创建一个类型混乱的DataFrame df_types pd.DataFrame({ price_str: [100, 200, 三百, 400], # 字符串包含中文 quantity: [5, 10, 15, 20], # 数字字符串 date_str: [2023-01-01, 2023-01-02, 2023-01-03, 2023-01-04] }) print(原始DataFrame及数据类型:) print(df_types) print(df_types.dtypes) # 转换数值类型errorscoerce将无法转换的设为NaN df_types[price_num] pd.to_numeric(df_types[price_str], errorscoerce) df_types[quantity_int] df_types[quantity].astype(int) # 如果确定都能转用astype # 转换日期类型 df_types[date_dt] pd.to_datetime(df_types[date_str], errorscoerce) print(\n转换类型后的DataFrame:) print(df_types[[price_str, price_num, quantity, quantity_int, date_str, date_dt]]) print(df_types.dtypes)6.4 字符串操作Pandas的字符串方法通过.str访问器调用非常方便。df_str pd.DataFrame({ email: [aliceexample.com, BOBTEST.COM, Charlie.Whitedomain.org] }) print(原始字符串列:) print(df_str) # 字符串操作 df_str[email_lower] df_str[email].str.lower() # 转小写 df_str[username] df_str[email].str.split().str[0] # 提取前的部分 df_str[domain] df_str[email].str.split().str[1] # 提取后的部分 df_str[has_dot] df_str[username].str.contains(\.) # 检查用户名是否包含点 print(\n应用字符串操作后:) print(df_str)7. 数据转换与高级操作7.1 新增列与列运算可以直接通过赋值来新增列列与列之间可以进行运算。# 使用之前的df print(原始df:) print(df) # 新增一列‘年薪’假设为月薪*13 df[年薪] df[薪资] * 13 print(\n新增‘年薪’列后:) print(df) # 新增一列‘年龄组’根据年龄进行分箱 bins [0, 25, 30, 40] # 定义区间边界 labels [25岁及以下, 26-30岁, 31-40岁] df[年龄组] pd.cut(df[年龄], binsbins, labelslabels, rightFalse) # rightFalse表示左闭右开 print(\n新增‘年龄组’列后:) print(df)7.2 应用函数apply和mapapply方法可以将一个函数应用到DataFrame的某一行或某一列上功能非常强大。# 对‘薪资’列应用一个函数例如计算税后薪资简单假设税率为10% def calculate_after_tax(salary): return salary * 0.9 df[税后薪资] df[薪资].apply(calculate_after_tax) # 也可以使用lambda表达式 df[税后薪资_lambda] df[薪资].apply(lambda x: x * 0.9) print(应用函数计算税后薪资:) print(df[[姓名, 薪资, 税后薪资, 税后薪资_lambda]]) # 对行应用函数axis1 def categorize_person(row): if row[年龄] 30 and row[薪资] 16000: return 青年高薪 elif row[年龄] 30: return 资深员工 else: return 其他 df[类别] df.apply(categorize_person, axis1) print(\n应用函数到每一行axis1:) print(df[[姓名, 年龄, 薪资, 类别]])map通常用于Series根据一个映射关系进行值替换。# 创建一个城市到区域的映射 city_to_region { 北京: 华北, 上海: 华东, 广州: 华南, 深圳: 华南 } df[区域] df[城市].map(city_to_region) print(\n使用map进行映射:) print(df[[城市, 区域]])7.3 分组聚合groupby分组聚合是数据分析的灵魂用于计算各组的统计信息。# 按‘城市’分组计算平均薪资和最大年龄 grouped df.groupby(城市).agg({ 薪资: mean, # 平均薪资 年龄: max, # 最大年龄 姓名: count # 人数 }).rename(columns{薪资: 平均薪资, 年龄: 最大年龄, 姓名: 人数}) # 重命名列 print(按城市分组聚合结果:) print(grouped) print(type(grouped)) # 结果是一个DataFrame # 更复杂的聚合对每个城市列出所有员工的姓名 df.groupby(城市)[姓名].apply(list)7.4 数据合并concat和mergeconcat用于沿轴行或列堆叠多个DataFrame。df1 pd.DataFrame({A: [A0, A1], B: [B0, B1]}) df2 pd.DataFrame({A: [A2, A3], B: [B2, B3]}) # 按行拼接纵向 result_concat pd.concat([df1, df2], ignore_indexTrue) print(按行拼接结果:) print(result_concat)merge用于基于一个或多个键将不同DataFrame中的行连接起来类似于SQL的JOIN操作。# 创建两个相关的DataFrame df_left pd.DataFrame({ 员工ID: [1, 2, 3, 4], 姓名: [张三, 李四, 王五, 赵六] }) df_right pd.DataFrame({ 员工ID: [1, 2, 3, 5], 部门: [技术部, 市场部, 技术部, 财务部] }) # 内连接 (inner join)只保留两个表都有的员工ID inner_merge pd.merge(df_left, df_right, on员工ID, howinner) print(内连接结果:) print(inner_merge) # 左连接 (left join)以左表为准 left_merge pd.merge(df_left, df_right, on员工ID, howleft) print(\n左连接结果:) print(left_merge)8. 实战案例销售数据分析现在让我们综合运用以上知识完成一个简单的销售数据分析案例。场景你有一份销售记录包含日期、产品类别、销售额和销售员。你需要加载数据。进行基本的数据探索和清洗。计算每个销售员的总销售额和平均销售额。找出销售额最高的产品类别。按月份分析销售额趋势。import pandas as pd import numpy as np # 1. 创建模拟销售数据 np.random.seed(42) # 固定随机种子确保结果可复现 dates pd.date_range(start2023-01-01, end2023-03-31, freqD) categories [电子产品, 家居用品, 服装, 食品] salespersons [Alice, Bob, Charlie] # 生成100条随机销售记录 n_records 100 sales_data pd.DataFrame({ 日期: np.random.choice(dates, n_records), 产品类别: np.random.choice(categories, n_records), 销售额: np.random.randint(100, 5000, n_records), 销售员: np.random.choice(salespersons, n_records) }) print(1. 原始销售数据前10行:) print(sales_data.head(10)) print(f数据形状: {sales_data.shape}) # 2. 数据清洗与探索 print(\n2. 数据基本信息:) print(sales_data.info()) print(\n数值列统计描述:) print(sales_data.describe()) print(\n检查缺失值:) print(sales_data.isnull().sum()) # 假设我们发现‘销售额’列有一个异常值为负数将其处理为NaN sales_data.loc[sales_data[销售额] 0, 销售额] np.nan # 填充缺失值用该产品类别的平均销售额填充 sales_data[销售额] sales_data.groupby(产品类别)[销售额].transform(lambda x: x.fillna(x.mean())) # 3. 计算每个销售员的总销售额和平均销售额 salesperson_stats sales_data.groupby(销售员).agg( 总销售额(销售额, sum), 平均销售额(销售额, mean), 订单数(销售额, count) ).round(2) # 保留两位小数 print(\n3. 销售员业绩统计:) print(salesperson_stats) # 4. 找出销售额最高的产品类别 category_sales sales_data.groupby(产品类别)[销售额].sum().sort_values(ascendingFalse) top_category category_sales.index[0] print(f\n4. 销售额最高的产品类别是: {top_category}, 总销售额为: {category_sales.iloc[0]:.2f}) print(各类别销售额排名:) print(category_sales) # 5. 按月份分析销售额趋势 # 首先新增一个‘月份’列 sales_data[月份] sales_data[日期].dt.to_period(M) # 转换为‘年月’周期 # 按月份和产品类别进行分组聚合 monthly_trend sales_data.groupby([月份, 产品类别])[销售额].sum().unstack(fill_value0) print(\n5. 按月度和产品类别的销售额趋势透视表:) print(monthly_trend) # 可视化需要matplotlib try: import matplotlib.pyplot as plt monthly_trend.plot(kindbar, figsize(10, 6)) plt.title(月度销售额趋势按产品类别) plt.xlabel(月份) plt.ylabel(销售额) plt.xticks(rotation0) plt.legend(title产品类别) plt.tight_layout() plt.show() print((图表已显示)) except ImportError: print((如需绘图请安装matplotlib: pip install matplotlib))9. 常见问题与排查思路在实际使用Pandas时你可能会遇到一些典型的错误和困惑。问题现象常见原因解决思路KeyError当使用df[‘列名’]时列名拼写错误、列名包含空格、列不存在。1. 使用df.columns打印所有列名仔细核对。2. 使用df.get(‘列名’, defaultNone)安全访问。3. 检查列名前后是否有空格df.columns df.columns.str.strip()。SettingWithCopyWarning警告在对DataFrame切片后的副本上进行赋值Pandas不确定你是想修改原始数据还是副本。1.明确意图如果确实想修改原始数据使用.loc或.iloc进行索引赋值如df.loc[df[‘A’] 0, ‘B’] 1。2. 如果只是想操作副本先显式复制df_copy df[df[‘A’] 0].copy()。读取CSV/Excel文件时中文乱码文件编码与read_csv/read_excel使用的编码不匹配。1. 尝试指定encoding‘utf-8’。2. 对于Windows系统生成的CSV常使用encoding‘gbk’或encoding‘gb2312’。3. 最通用的是encoding‘utf-8-sig’它能处理带BOM的UTF-8文件。AttributeError: module ‘pandas’ has no attribute ‘Int64Index’使用了过时的API。在较新版本的Pandas中Int64Index等已被整合到通用的pd.Index中。1. 检查Pandas版本print(pd.__version__)。2. 查阅对应版本的官方文档使用新的API。例如直接使用pd.Index或df.index。使用apply函数速度慢apply是逐行/逐列操作的数据量大时效率低。1. 优先使用Pandas内置的向量化操作如df[‘col’] * 2。2. 如果必须用apply尝试减少函数复杂度。3. 对于复杂转换考虑使用np.vectorize或swifter库针对大数据。dtype为object无法进行数值计算列中可能混合了字符串和数字或者全是数字但被读成了字符串。1. 使用pd.to_numeric(errors‘coerce’)强制转换无法转换的会变成NaN。2. 检查数据源清理非数值字符。分组聚合后索引变成了分组列这是groupby().agg()的默认行为。1. 如果希望分组列作为普通列在聚合时使用as_indexFalse参数df.groupby(‘key’, as_indexFalse).agg(...)。2. 聚合后使用reset_index()方法重置索引。10. 最佳实践与性能优化建议掌握了基本操作后遵循一些最佳实践能让你的代码更健壮、更高效。1. 明确数据类型在读取数据后尽早使用df.info()和df.dtypes检查数据类型。将分类数据转换为category类型可以大幅节省内存并提升groupby等操作的速度。df[城市] df[城市].astype(category)2. 避免链式赋值链式赋值如df[df[‘A’] 0][‘B’] 1是导致SettingWithCopyWarning的元凶也容易产生不可预知的行为。始终使用.loc/.iloc进行单次赋值。3. 利用向量化操作Pandas的底层基于NumPy其向量化操作比循环快几个数量级。# 慢使用循环 for i in range(len(df)): df.loc[i, new_col] df.loc[i, old_col] * 2 # 快使用向量化 df[new_col] df[old_col] * 24. 处理大数据集时使用分块读取如果文件太大无法一次性读入内存可以使用chunksize参数。chunk_iter pd.read_csv(huge_file.csv, chunksize100000) for chunk in chunk_iter: # 处理每个数据块 process(chunk)5. 使用query方法进行复杂查询当筛选条件非常复杂时query方法可以使代码更清晰。# 传统布尔索引 result df[(df[年龄] 25) (df[城市].isin([北京, 上海])) (df[薪资] 20000)] # 使用query result df.query(年龄 25 and 城市 in [北京, 上海] and 薪资 20000)6. 保存处理进度对于耗时的数据处理流程可以阶段性地将中间结果保存为pickle或feather格式它们比CSV读写更快且能保留数据类型。df.to_pickle(processed_data.pkl) # 读取 df pd.read_pickle(processed_data.pkl)7. 编写可复现的代码使用pd.set_option设置显示选项确保每次运行结果一致。对于随机操作固定随机种子。pd.set_option(display.max_columns, None) # 显示所有列 pd.set_option(display.float_format, {:.2f}.format) # 浮点数格式 np.random.seed(123) # 固定随机种子通过本文的系统学习你应该已经掌握了Pandas从环境搭建、核心数据结构、数据读写、查询筛选、清洗转换到分组聚合的完整知识链。真正的熟练来自于实践建议你寻找自己感兴趣的数据集如Kaggle上的公开数据集重复本文中的操作并尝试解决更复杂的问题。接下来你可以进一步学习Pandas的时间序列处理、窗口函数、多层索引等高级功能并探索其与Matplotlib/Seaborn可视化库、Scikit-learn机器学习库的协同工作。记住在数据科学的世界里Pandas是你手中最可靠的那把钥匙。

相关新闻

最新新闻

KeyShot 2025 实时渲染软件:从安装部署到专业渲染工作流全解析

KeyShot 2025 实时渲染软件:从安装部署到专业渲染工作流全解析

KeyShot 是一款专注于实时渲染的 3D 渲染和动画软件,以其直观的操作和高质量的物理渲染引擎而闻名。它并非一个需要本地部署、关注显存占用的 AI 模型,而是一款成熟的商业设计工具。对于设计师、工程师和 3D 艺术家而言,KeyShot 的核心价值在…

2026/9/1 5:06:28
零基础Kali Linux渗透测试入门:从环境搭建到靶场实战全指南

零基础Kali Linux渗透测试入门:从环境搭建到靶场实战全指南

这次我们来看一个面向零基础学习者的 Kali Linux 渗透测试教程合集。对于很多想入门网络安全、了解渗透测试的朋友来说,Kali Linux 是一个绕不开的工具集,但复杂的命令和陌生的环境往往让人望而却步。这个系列教程的核心价值在于,它试图将庞大…

2026/9/1 5:06:28
用Python实现COC跑团判定模拟器:从规则到状态机的边界处理

用Python实现COC跑团判定模拟器:从规则到状态机的边界处理

带过几次 COC 跑团后,你会发现自己其实在同时维护三样东西:一份讲得通的故事脚本、一堆需要随时计算的骰点,以及一叠随时可能被玩家改出上界的角色卡。前阵子看到《绝望的孤岛》这类克苏鲁神话跑团熟肉,弹幕里不少人刷“bug 一样鬼…

2026/9/1 5:06:28
MKVToolNix 95版:跨平台开源视频封装工具,无损合并提取音轨字幕

MKVToolNix 95版:跨平台开源视频封装工具,无损合并提取音轨字幕

1. 先搞清楚 MKVToolNix 到底能帮你解决什么如果你经常下载视频、处理影视资源,或者需要把多个视频片段、音轨、字幕文件打包成一个文件,那你大概率听说过或者用过 MKVToolNix。它不是一个单一的“视频合并软件”,而是一套功能强大、跨平台的…

2026/9/1 5:06:28
从《明日方舟》同人游戏SamiExpedition Demo,学习Godot引擎与GDScript游戏开发实战

从《明日方舟》同人游戏SamiExpedition Demo,学习Godot引擎与GDScript游戏开发实战

如果你是一名《明日方舟》的玩家,同时又对游戏开发抱有兴趣,那么最近在社区里流传的一个名字可能会让你眼前一亮:SamiExpedition。这不是鹰角网络官方的更新,而是一款由玩家社区驱动的同人游戏项目,目前已经放出了 Dem…

2026/9/1 5:06:28
每赚100美元,40归云:这周赚钱的,是会用AI的人

每赚100美元,40归云:这周赚钱的,是会用AI的人

100 美元进账,40 美元被云厂商拿走——这不是我算的,是巴克莱给 AI 模型公司算的账。这周,AI 圈最扎心的一件事:钱,正在从"卖模型"的手里溜走。读完你就会看懂,这周 AI 的账到底被谁赚走了,以及普通人在里面能站上哪一环。 先看账:模型公司每赚 100 美元,40 美元归了…

2026/9/1 5:01:28