系统设置
# 1.显示所有的行列(不显示省略号)
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)
csv操作
从csv读取
# 读取csv文件,返回DataFrame
data_csv = pd.read_csv('./xxx.csv')
# 读取csv二进制流
df = pd.read_csv(io.BytesIO(csv_data_binary))
保存到csv
# 保存为csv
df.to_csv('./xxx.csv', index=False)
数据库操作
解决报错:TypeError: __init__() got multiple values for argument 'schema'
# 卸载2.0.0以上的版本
pip uninstall sqlalchemy
# 更换为1.4.35版本
pip install -i https://mirrors.aliyun.com/pypi/simple sqlalchemy==1.4.35
从mysql读取
from sqlalchemy import create_engine
import pandas as pd
engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/crop")
# 读取数据
df = pd.read_sql_table("user", engine)
# 打印数据
print(df.head())
保存到mysql
from sqlalchemy import create_engine
import pandas as pd
engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/crop")
data = pd.read_csv('./gao.csv')
data.to_sql(name='data', con=engine, if_exists='append', index=False, index_label=False)
查询数据时传参
- 方式1:直接拼接,可能会有SQL注入的危险
city = 'Lahore'
crop = 'Apple (Ammre)'
sql = "select * from data where city='%s' and crop='%s'" % (city, crop) # 不要忘记单引号
df = pd.read_sql(sql, engine)
- 方式2:可能无法做到in查询
sql = "select * from data where city=%s and crop=%s"
params = ['Lahore', 'Apple (Ammre)']
df = pd.read_sql(sql, engine, params=params)
- 方式3:可以实现in查询
sql = "select * from data where city=%(city)s and crop=%(crop)s"
params = {'city': 'Lahore', 'crop': 'Apple (Ammre)'}
df = pd.read_sql(sql, engine, params=params)
- pymysql传参时传入表名:
sql = "select * from {} where city=%(city)s and crop=%(crop)s".format(Data.__tablename__)
params = {'city': city, 'crop': crop}
data = pd.read_sql(sql, engine, params=params)
df.to_sql
对表的情况
# 不存在tb_price表则创建;存在则追加
df.to_sql(name='tb_price', con=engine, if_exists='append', index=False, index_label=False)
# 直接替换
df.to_sql(name='tb_price', con=engine, if_exists='replace', index=False, index_label=False)
建立主键
- 导入表时自动将索引作为主键,且名字为’id’
df.to_sql(name='tb_price', con=engine, if_exists='replace', index=True, index_label='id')
- 但如果只这样做,数据库形成的id的约束是MUL类型的key,还要执行下面的代码转为PRIMARY KEY
# 执行SQL,将id列设置为主键 with engine.connect() as con: con.execute('ALTER TABLE tb_price ADD PRIMARY KEY (id)')
字段类型转换
-
df导入数据库时数据类型一般都是text,如何在真正写入表时转为期望类型?我们可能会在to_sql之前直接改变df的类型。
# 字符串 df[column] = df[column].astype('str') # 整数 df[column] = df[column].astype('int64') # 浮点数 df[column] = df[column].astype('float') # 日期datetime df[column] = pd.to_datetime(df[column])
-
但这样不好,推荐下面的做法:
from sqlalchemy.dialects.mysql import FLOAT, VARCHAR, DATETIME columns_type = { 'prodName': VARCHAR(64), 'prodCat': VARCHAR(64), 'prodPcat': VARCHAR(64), 'lowPrice': FLOAT(10, 2), 'highPrice': FLOAT(10, 2), 'avgPrice': FLOAT(10, 2), 'unitInfo': VARCHAR(32), 'pubDate': DATETIME } # 指定dtype参数 df.to_sql(name='tb_price', con=engine, if_exists='replace', index=True, index_label='id', dtype=columns_type)
-
注意sqlalchemy数据类型转换的坑。所以,干脆我们都用dialects.mysql的(上面)
from sqlalchemy import String, DateTime, Float from sqlalchemy.dialects.mysql import FLOAT columns_type = { 'prodName': String(64), 'prodCat': String(64), 'prodPcat': String(64), # 'lowPrice': Float(10, 2), # 不管用 'lowPrice': FLOAT(precision=10, scale=2), 'highPrice': FLOAT(precision=10, scale=2), 'avgPrice': FLOAT(precision=10, scale=2), 'unitInfo': String(32), 'pubDate': DateTime }
np操作
- np.array和np.ndarray的区别
- np.ndarray是array([113.209]),怎么转化为float的113.209?
arr = np.array([113.209]) # 索引 num_float = float(arr[0]) # 元素值 num_float = arr.item()
df操作
更改索引:df的索引默认是0, 怎么从1开始(引入导入数据库时index就是id,而id一般从1开始)?
df.index += 1
调换两列位置:比如原本的df为B,C,A共3列数据,我想将列顺序更改为A,B,C,则参考下面:
lists = [
['迪丽热巴', '1班', '11111', '15'],
['古力娜扎', '2班', '22222', '10'],
['玛尔扎哈', '2班', '33333', '10'],
]
# 原本的列顺序
df = pd.DataFrame(lists, columns=['姓名', '班级', '学号', '学时'])
# 调换为下面的列顺序
df = df[['班级', '姓名', '学号', '学时']]
df.to_excel('./test.xlsx', index=False)
新增一列索引列:假如csv文件只有EventId,EventTemplate,Occurrences
三列,如何在读取后增加一列,表示序号?
df = pd.read_csv('./assets/HDFS_2k.log_templates.csv')
print(df)
# 新增索引列
df.reset_index(inplace=True)
print(df)
-
新增前:
-
新增后
根据字典列表构建df:
item_list = [
{'name': 'AAA', 'value': 'AAA', 'date': '2023/11/20'},
{'name': 'BBB', 'value': 'BBB', 'date': '2023/11/20'},
{'name': 'CCC', 'value': 'CCC', 'date': '2023/11/20'},
{'name': 'DDD', 'value': 'DDD', 'date': '2023/11/20'},
{'name': 'EEE', 'value': 'EEE', 'date': '2023/11/20'},
]
df = pd.DataFrame(item_list, columns=['name', 'value', 'date'])
# print(df)
# df.to_csv() ...
构建空df后添加数据:创建空的包含指定列的DataFrame,并且每次循环中逐一添加元素。注意df不会原地操作!必须重新赋值!
# 创建一个空的DataFrame
df = pd.DataFrame(columns=['name', 'value', 'date'])
# 在循环中逐个添加行
for i in range(10):
name = input("请输入name: ") # 从用户输入获取name
value = float(input("请输入value: ")) # 从用户输入获取value
date = input("请输入date: ") # 从用户输入获取date
# 创建一个包含新行的字典
row = {'name': name, 'value': value, 'date': date}
# 将新行添加到DataFrame中,注意ignore_index=True
df = df.append(row, ignore_index=True)
print(df)
回归模型
一元多次回归
import numpy as np
import matplotlib.pyplot as plt
# 生成散点数据
x = np.linspace(-5, 5, 30)
y_true = 2 * x ** 3 - 3 * x ** 2 + 4 * x - 1
y_noise = np.random.normal(0, 20, len(x))
y = y_true + y_noise
x_test = np.linspace(4, 6, 10)
y_test_true = 2 * x_test ** 3 - 3 * x_test ** 2 + 4 * x_test - 1
y_noise = np.random.normal(0, 15, len(x_test))
y_test = y_test_true + y_noise
# 曲线拟合
delta = 3
coefficients = np.polyfit(x, y, delta)
fitted_curve = np.poly1d(coefficients)
# 绘制散点图和回归曲线
plt.scatter(x, y, label='trainX & trainY')
plt.scatter(x_test, y_test, label='testX & testY')
plt.plot(x, fitted_curve(x), color='red', label='y=ax^3+bx^2+cx+d')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.title('Regression')
plt.savefig('./data.png')
替换nan
方法:
def replace_nan(arr):
for i in range(arr.shape[1]): # 遍历所有列
temp_col = arr[:, i] # 当前每一列
if np.isnan(sum(temp_col)): # 如果有nan
not_nan_col = temp_col[temp_col == temp_col] # 去除nan
temp_col[np.isnan(temp_col)] = np.mean(not_nan_col) # 将nan替换为均值
return arr
测试:
if __name__ == '__main__':
data = np.array(range(12)).reshape((3, 4))
# 赋值nan必须将数据类型转化为"float"
data = data.astype("float")
data[2, 2:] = np.nan
print(data)
print('=' * 30)
data = replace_nan(data)
print(data)