数据结构
- Series 一维
- DataFrame 二维,或多维
之前的 Pannel 三维数组完全可以用 DataFrame 嵌套表示。
后来被移除了,挺好的。
pd.Series(
data=None,
index=None,
dtype=None,
name=None,
copy=False,
fastpath=False,
)
pd.DataFrame(
data=None,
index: 'Optional[Axes]' = None,
columns: 'Optional[Axes]' = None,
dtype: 'Optional[Dtype]' = None,
copy: 'bool' = False,
)
连接 concat
pd.concat(
objs: Union[Iterable[ForwardRef('NDFrame')], Mapping[Optional[Hashable], ForwardRef('NDFrame')]],
axis=0,
join='outer',
ignore_index: bool = False,
keys=None,
levels=None,
names=None,
verify_integrity: bool = False,
sort: bool = False,
copy: bool = True,
) -> Union[ForwardRef('DataFrame'), ForwardRef('Series')]
df1 = pd.DataFrame({'key': tuple('abcd'), 'data': range(1, 5)})
df2 = pd.DataFrame({'key': tuple('abcd'), 'data': range(6, 10)})
pd.concat([df1, df2])
合并 merge
pd.merge(
left,
right,
how: str = 'inner',
on=None,
left_on=None,
right_on=None,
left_index: bool = False,
right_index: bool = False,
sort: bool = False,
suffixes=('_x', '_y'),
copy: bool = True,
indicator: bool = False,
validate=None,
) -> 'DataFrame'
df1 = pd.DataFrame(range(10))
df2 = pd.DataFrame(range(20))
df3 = pd.merge(df1, df2)
df4 = pd.DataFrame({'a': 1, 'b': 2}, index=['x', 'y'])
df5 = pd.DataFrame({'key': 'abcd', data=range(4)})
pd.merge(df4, df5)
how 参数:
left
左连接right
右连接inner
内连接outer
外连接cross
交叉连接,笛卡儿积
分组
import random
所有姓名 = ('小李 四眼 大红 雀儿 宝宝 山鸡 皮蛋 猴子 芝麻 拐子 蝴蝶 '
'乐高 五花 伟哥 金子 老班 旺仔 二狗 圆圆 熊猫 泰迪 婆婆 '
'小白 小强 电脑').split(' ')
所有学科 = ('语文 数学 英语 物理 化学 生物 历史 地理 政治 体育 实践').split(' ')
# 成绩表 = {姓名: {学科: random.choice('SABCD') for 学科 in 所有学科} for 姓名 in 所有姓名}
# 成绩 = pd.DataFrame({学科: [成绩表[姓名][学科] for 姓名 in 所有姓名] for 学科 in 所有学科}, index=所有姓名)
def 评级(分数):
if 分数 < 60:
return 'D'
elif 分数 < 75:
return 'C'
elif 分数 < 85:
return 'B'
elif 分数 < 95:
return 'A'
return 'S'
成绩表 = {姓名: {学科: random.randint(60, 100) for 学科 in 所有学科} for 姓名 in 所有姓名}
for 成绩 in 成绩表.values():
成绩['总分'] = sum(成绩.values())
成绩['评级'] = 评级(成绩['总分'] / len(所有学科))
所有条目 = 所有学科 + ['总分', '评级']
成绩 = pd.DataFrame({条目: [成绩表[姓名][条目] for 姓名 in 所有姓名] for 条目 in 所有条目}, index=所有姓名)
成绩
grouped = 成绩['总分'].groupby(成绩['评级'])
grouped
# <pandas.core.groupby.generic.SeriesGroupBy object at 0x7f248a930460>
grouped.mean()
# 评级
# A 938.000000
# B 876.954545
# C 813.000000
# Name: 总分, dtype: float64
聚合
grouped = 成绩.groupby(成绩['评级'])
grouped
# <pandas.core.groupby.generic.DataFrameGroupBy object at 0x7f248a981e20>
grouped.mean()
grouped['总分'].mean()
grouped['语文'].quantile(0.9)
appregate
def peak_to_peak(arr):
return arr.max() - arr.min()
# .aggregate(func=None, *args, engine=None, engine_kwargs=None, **kwargs)
# 有一个别名:.agg
grouped.agg(peak_to_peak)
grouped['总分'].agg(peak_to_peak)
# 这个很不错,计算每一列的 count, mean, std, min, 0.25, 0.50, 0.75, max
grouped.describe()
top
def top(df, n=1, column='语文'):
return df.sort_values(by=column)[-n:]
top(成绩)
grouped.apply(top)
缺失数据处理
.isnull
=> 找到None
,np.nan
.dropna
=> data[data.notnull()].fillna
pf1 = pd.Series(['a', 'b', '12', 12, True, None, [], (), {}, set(), np.nan])
pf1
pf1.isnull()
data = pd.DataFrame([[1, 2, None], [5, None, 4]])
data
data.dropna()
data.dropna(how='all')
data.dropna(thresh=2)
data.fillna(0, inplace=True)
data.fillna({1: 50, 2: 100})
data = pd.DataFrame(np.random.randn(4, 5))
data.iloc[:2, 1] = data.iloc[:3, 2] = np.nan
data
data = pd.DataFrame({
'a': [random.choice(['one', 'two', 'three', 'four']) for _ in range(10)],
'b': [random.choice(['jim', 'may', 'jacob', 'lucy']) for _ in range(10)],
})
data
data.duplicated()
data.drop_duplicated()
data['c'] = range(10)
data
data.duplicated()
data.drop_duplicates(['a']) # 按列去重
data.drop_duplicates(['a', 'b'])
data.drop_duplicates(['a', 'b'], keep='last')
# a = data['a'].str.lower()
a = data['a']
data['d'] = a.map({'one': 'O', 'two': 'T', 'three': 'T', 'four': 'F'})
import random
所有姓名 = ('小李 四眼 大红 雀儿 宝宝 山鸡 皮蛋 猴子 芝麻 拐子 蝴蝶 '
'乐高 五花 伟哥 金子 老班 旺仔 二狗 圆圆 熊猫 泰迪 婆婆 '
'小白 小强 电脑').split(' ')
所有学科 = ('语文 数学 英语 物理 化学 生物 历史 地理 政治 体育 实践').split(' ')
成绩表 = {姓名: {学科: random.randint(60, 100) for 学科 in 所有学科} for 姓名 in 所有姓名}
成绩 = pd.DataFrame({学科: [成绩表[姓名][学科] for 姓名 in 所有姓名] for 学科 in 所有学科}, index=所有姓名)
成绩['语文'].map(lambda x: 评级(x))
replace
data = pd.Series(np.random.randint(1, 100, 100))
data.to_string()
data.replace(1, np.nan, inplace=True)
data.replace([1, 2], np.nan, inplace=True)
data.replace(range(10), np.nan, inplace=True)
data.replace([1, 2], [0, np.nan], inplace=True) # 必须相同长度
data.replace({1: 0, 2: np.nan}, inplace=True)
data[data.isnull()]
filter
成绩['语文'][成绩['语文'] > 90]
成绩[成绩['语文'] > 90]
# np.sum(成绩)
成绩[np.sum(成绩) > 2000] # 平均分达到 80 的科目,即 25 个人,总分 2000
# 成绩.sum(axis=1)
成绩[成绩.sum(axis=1) > 900] # 总分超过 900 分的人
data = pd.DataFrame(np.random.randn(10, 10))
data.describe()
data[np.abs(data[0]) < 1] # 列出第 0 列绝对值小于 1 的行
data[(np.abs(data) < 1).any(1)] # 列出所有列 绝对值小于 1 的行
data.iloc[:,(np.abs(data) < 1).any(0)]
其他数据来源
csv
参数超级多,就不搬到这里来了。
pd.read_csv()
pd.read_table()
JSON
pd.read_json()
Excel
Excel,无人不知,无人不晓,可以认为是一种数据存储和可视化工具。
pd.read_excel()
数据库
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_sql.html
只要支持 Python DB-API 就行。
# pandas.read_sql(sql, con,
# index_col=None,
# coerce_float=True,
# params=None,
# parse_dates=None,
# columns=None,
# chunksize=None)
# pandas.read_sql_query(sql, con,
# index_col=None,
# coerce_float=True,
# params=None,
# parse_dates=None,
# chunksize=None)
# pandas.read_sql_table(table_name, con,
# schema=None,
# index_col=None,
# coerce_float=True,
# parse_dates=None,
# columns=None,
# chunksize=None)
df = pd.read_sql(sql, con=conn)
df = pd.read_sql(sql, con=conn, index_col='id')