开篇
之前一直用 list 和 dict 存数据,直到学数据分析才发现,Pandas 里有自己的"容器":**DataFrame(表格)**和 Series(一列)。这一篇我先把"怎么造出一张表"这件事搞明白。
创建 DataFrame 的四种方式
我先从最简单的入手,把三行数据写成三个字典组成的列表:
df1 = pd.DataFrame([
{"name": "Alice", "age": 25},
{"name": "Bob", "age": 30},
{"name": "Charlie", "age": 35}
])
跑出来就是一张三列两行的表(外加左边的行索引)。方式一:列表套字典,每个字典是一行,字典的键自动变成列名。
方式二:字典套列表,把每一列的值写成列表:
df2 = pd.DataFrame({
"name": "Alice", "Bob", "Charlie",
"age": 25, 30, 35
})
我发现 df1 和 df2 的结果一模一样,只是"喂数据"的角度不同:一个按行喂,一个按列喂。实际写数据清洗代码时,按列喂(方式二)更常见,因为爬虫或接口返回的数据常常就是"一列一列"的。
方式三:二维列表 + 手动指定列名。如果只有裸数据、没有字段名:
df3 = pd.DataFrame(
\['Alice', 25, 'Bob', 30, 'Charlie', 35],
columns="name", "age"
)
这时不写 columns 的话,列名就变成 0、1 这样的数字,所以列名一定要补上。
方式四:再顺手自定义行索引,在方式三基础上加 index='a', 'b', 'c',左边那列"行名字"就从 0/1/2 变成 a/b/c。这个看着不起眼,后面用 loc 按名字选行时就知道它有多重要了。
DataFrame 的常见属性
表造好了,我拿 df4(自定义过索引的那张)把常用属性挨个试了一遍:
df4.index.tolist() ------ 取索引,转成普通列表看着更舒服
df4.columns.tolist() ------ 取列名
df4.values.tolist() ------ 取纯数据,丢掉表头
df4.size ------ 元素总个数(2 列 × 3 行 = 6)
df4.dtypes ------ 每一列的数据类型,注意 name 列显示的是 object 而不是字符串
df4.shape ------ 维度,返回 (3, 2),行列各是多少
我的理解是:.tolist() 是把 Pandas 自己的东西"翻译"回 Python 原生 list,当你只想要数据、不想要表格结构时就用它。
Series 的四种创建方式
Series 可以理解成"带索引的一列数据":
s1 = pd.Series(10, 20, 30, 40, 50)
s2 = pd.Series((10, 20, 30, 40, 50), index='a','b','c','d','e')
s3 = pd.Series({'a': 10, 'b': 20, 'c': 30})
s4 = df4'name'
前三种分别是传列表、传元组并指定索引、传字典(字典的键自动成为索引)。第四种最实用:直接从 DataFrame 里抽一列出来,它天然就是一个 Series------这也解释了为什么取单列是单个方括号,而取多列要写两个方括号。
Series 的属性比 DataFrame 少一个维度:s3.index.tolist()、s3.values.tolist()、s3.size、s3.dtype(注意是 dtype 没有 s,因为一列里类型统一)、s3.shape(返回 (3,),只有一个长度)。
小结
这一篇我把"造数据"这件事过完了。我自己的记忆法是:DataFrame 是字典的升级版,Series 是列表的升级版;行索引是它的"名字",.tolist() 是它回归原生 Python 的出口。