json

1
2
3
4
5
6
7
8
9
10
11
def read_json_lines():
"""
读取.json文件,但.json文件存的是.jsonl的格式
文件末尾是否为空行,都可读取
"""
json_path = Path("./tmp_data/ori_val.json")
data_list = []
with open(json_path, mode='r', encoding='utf-8') as f:
for data in f.readlines():
data_list.append(json.loads(data))
print('done')
1
2
3
4
5
6
7
8
9
10
11
12
13
def read_json():
"""此.json文件,类似报文数据"""
json_path = Path("./tmp_data/tmp_val.json")
with open(json_path, mode='r', encoding='utf-8') as f:
# json.load(f),从文件f中读取json格式的str,转为dict对象
data = json.load(f)
print(data)
print('done')

# json.loads(data),读取json格式的str,转为dict对象
# tmp_str = '{"0": "others", "1": "时间不当", "2": "平常拒绝", "3": "强烈反感"}'
# data = json.loads(tmp_str)
# print('done')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def write_json():
json_path = Path("./tmp_data/tmp_new_val.json")
if json_path.exists():
json_path.unlink()
json_path.touch(exist_ok=False)

data = {
"0": "others",
"1": "时间不当",
"2": "平常拒绝",
"3": "强烈反感"
}

# json.dump(data, f),将data转为json格式的str,并写入文件f
with open(json_path, mode='w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False)

# json.dumps(data),仅将data转为json格式的str
# with open(json_path, mode='w', encoding='utf-8') as f:
# json_data = json.dumps(data, ensure_ascii=False)
# f.write(json_data)

print('done')

jsonl

1
2
3
4
5
6
7
8
9
10
def read_jsonl():
"""文件末尾是否为空行,都可读取"""
jsonl_path = Path("./tmp_data/tmp_val.jsonl")
data_list = []
with open(jsonl_path, mode='r', encoding='utf-8') as f:
for line in f.readlines():
data = json.loads(line)
data_list.append(data)
print(data)
print('done')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def write_w_jsonl():
dict_1 = {'param_1': 'val_1', 'param_2': 'val_2', 'param_3': 'val_3'}
dict_2 = {'param_1': 'val_4', 'param_2': 'val_5', 'param_3': 'val_6'}
dict_3 = {'param_1': 'val_7', 'param_2': 'val_8', 'param_3': 'val_9'}
data_list = [dict_1, dict_2, dict_3]

jsonl_path = Path("./tmp_data/tmp_val.jsonl")
if jsonl_path.exists():
jsonl_path.unlink()
jsonl_path.touch(exist_ok=False)

with open(jsonl_path, mode='w', encoding='utf-8') as f:
# 避免了最末尾空行
lines = [json.dumps(data, ensure_ascii=False) for data in data_list]
f.write('\n'.join(lines))
print('done')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def write_a_jsonl():
dict_1 = {'param_1': 'val_1', 'param_2': 'val_2', 'param_3': 'val_3'}
dict_2 = {'param_1': 'val_4', 'param_2': 'val_5', 'param_3': 'val_6'}
dict_3 = {'param_1': 'val_7', 'param_2': 'val_8', 'param_3': 'val_9'}

jsonl_path = Path("./tmp_data/tmp_val.jsonl")
if jsonl_path.exists():
jsonl_path.unlink()
jsonl_path.touch(exist_ok=False)

with open(jsonl_path, mode='a', encoding='utf-8') as f:
f.writelines([json.dumps(dict_1, ensure_ascii=False) + '\n'])
with open(jsonl_path, mode='a', encoding='utf-8') as f:
f.writelines([json.dumps(dict_2, ensure_ascii=False) + '\n'])
with open(jsonl_path, mode='a', encoding='utf-8') as f:
f.writelines([json.dumps(dict_3, ensure_ascii=False) + '\n'])
# 用.txt打开时,最后末尾为空行
# 实际的数据为:
# ......\n
# ......\n
# ......\n
# `read_jsonl`函数可以正常读取,data_list的最后元素不会是空元素
print('done')

txt

1
2
3
4
5
6
7
def read_txt_lines():
txt_path = Path("./tmp_data/tmp_val.txt")
data_list = []
with open(txt_path, mode='r', encoding='utf-8') as f:
for line in f.readlines():
data_list.append(line.strip()) # `strip()`方法移除每行字符串首尾的空白字符,包括换行符
print('done')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def write_a_txt_lines():
txt_path = Path("./tmp_data/new_val.txt")
if txt_path.exists():
txt_path.unlink()
txt_path.touch(exist_ok=False)

str_1 = "row_1"
str_2 = "row_2"
str_3 = "row_3"

with open(txt_path, mode='a', encoding='utf-8') as f:
f.writelines(str_1 + '\n')
with open(txt_path, mode='a', encoding='utf-8') as f:
f.writelines(str_2 + '\n')
with open(txt_path, mode='a', encoding='utf-8') as f:
f.writelines(str_3 + '\n')
print('done')
1
2
3
4
5
6
7
8
9
10
11
12
def write_w_txt_lines():
txt_path = Path("./tmp_data/new_val.txt")
if txt_path.exists():
txt_path.unlink()
txt_path.touch(exist_ok=False)

data_list = ["row_1", "row_2", "row_3"]

with open(txt_path, mode='w', encoding='utf-8') as f:
# 避免了最末尾空行
f.write('\n'.join(data_list))
print('done')

dataframe

tsv

1
2
3
4
5
6
7
8
9
def read_tsv():
tsv_path = Path("./tmp_data/dev.tsv")
# 如果`.tsv`文件没有包含列名的行,`pandas`默认会将第一行数据作为列名。
# 可以通过手动添加额外参数的方式来指定列名
# `header=None`参数告诉`pandas`,该文件没有列名行
# `names`参数用来提供列名列表,添加额外的列名行
df = pd.read_csv(tsv_path, sep='\t', encoding='utf-8', header=None, names=['col_1', 'col_2'])
print(df)
print('done')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def write_w_tsv():
tsv_path = Path("./tmp_data/test.tsv")
if tsv_path.exists():
tsv_path.unlink()
tsv_path.touch(exist_ok=False)

df = pd.DataFrame(columns=['col_1', 'col_2']) # 创建一个空的DataFrame,但指定列名
df.loc[0] = ['0', 'aaa'] # `.loc[0]`是行索引
df.loc[1] = ['1', 'bbb']
df.loc[2] = ['0', 'ccc']

# `sep='\t'` `.tsv`文件的标准分隔符
# `index=False` 不会将df每行的索引,作为第一列写入文件
# `header=False` 不会将df每列的列名,作为第一行写入文件
# `columns=['col_1', 'col_2']` 仅将这两个列的数据写入文件,且指定列名顺序
df.to_csv(tsv_path, mode='w', sep='\t', index=False, header=False, columns=['col_1', 'col_2'])
print('done')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def write_a_tsv():
tsv_path = Path("./tmp_data/test.tsv")
if tsv_path.exists():
tsv_path.unlink()
tsv_path.touch(exist_ok=False)

df_1 = pd.DataFrame(columns=['col_1', 'col_2']) # 创建一个空的DataFrame,但指定列名
df_1.loc[0] = ['0', 'aaa'] # `.loc[0]`是行索引
df_1.loc[1] = ['1', 'bbb']
df_1.loc[2] = ['0', 'ccc']

df_2 = pd.DataFrame(columns=['col_1', 'col_2'])
df_2.loc[0] = ['0', 'ddd']
df_2.loc[1] = ['1', 'eee']
df_2.loc[2] = ['0', 'fff']

df_1.to_csv(tsv_path, mode='w', sep='\t', index=False, header=False, columns=['col_1', 'col_2'])
df_2.to_csv(tsv_path, mode='a', sep='\t', index=False, header=False, columns=['col_1', 'col_2'])
print('done')

csv

1
2
3
4
5
6
7
8
def read_csv():
csv_path = Path("./tmp_data/test.csv")
# `header=0`: 用于指定第0行作为df的列名行。(因为原csv_path文件中已存储了列名行) (若不手动指定,header参数默认为0)
# 不要使用`names`参数,该参数用于添加额外的列名行
# `index_col=0`: 用于指定第0列作为df的行索引(因为原csv_path文件中已存储了索引列),而不是自动生成从0开始的整数序列
df = pd.read_csv(csv_path, encoding='utf-8', header=0, index_col=0)
print(df)
print('done')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def write_w_csv():
csv_path = Path("./tmp_data/test.csv")
if csv_path.exists():
csv_path.unlink()
csv_path.touch(exist_ok=False)

df = pd.DataFrame(columns=['col_1', 'col_2']) # 创建一个空的DataFrame,但指定列名
df.loc[0] = ['0', 'aaa']
df.loc[1] = ['1', 'bbb']
df.loc[2] = ['0', 'ccc']

# `index=True`: 将df每行的索引,作为第一列写入文件。(即保留行索引)
# `header=True`: 将df每列的列名,作为第一行写入文件。(即保留列名)
# `columns=['col_1', 'col_2']`: 仅将这两个列的数据写入文件,且指定列名顺序
df.to_csv(csv_path, mode='w', index=True, header=True, columns=['col_1', 'col_2'])
print('done')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def write_a_csv():
csv_path = Path("./tmp_data/test.csv")
if csv_path.exists():
csv_path.unlink()
csv_path.touch(exist_ok=False)

df_1 = pd.DataFrame(columns=['col_1', 'col_2']) # 创建一个空的DataFrame,但指定列名
df_1.loc[0] = ['0', 'aaa']
df_1.loc[1] = ['1', 'bbb']
df_1.loc[2] = ['0', 'ccc']

df_2 = pd.DataFrame(columns=['col_1', 'col_2']) # 创建一个空的DataFrame,但指定列名
df_2.loc[0] = ['0', 'ddd']
df_2.loc[1] = ['1', 'eee']
df_2.loc[2] = ['0', 'fff']

# 将df_1写入.csv文件,保留索引,保留列名
# `index=True`: 将df每行的索引,作为第一列写入文件。(即保留行索引)
# `header=True`: 将df每列的列名,作为第一行写入文件。(即保留列名)
# `columns=['col_1', 'col_2']`: 仅将这两个列的数据写入文件,且指定列名顺序
df_1.to_csv(csv_path, mode='w', index=True, header=True, columns=['col_1', 'col_2'])
# 获取df_1最后一个索引
last_index = df_1.index[-1]

# 手动更新df_2的索引,使其接续df_1
df_2.index = range(last_index + 1, last_index + 1 + len(df_2))
# df_2追加写入,保留索引,但不保留列名,
df_2.to_csv(csv_path, mode='a', index=True, header=False, columns=['col_1', 'col_2'])

print('done')

xlsx

1
2
3
4
5
6
7
8
def read_xlsx():
xlsx_path = Path("./tmp_data/test.xlsx")
# `header=0`: 用于指定第0行作为df的列名行。(因为原xlsx_path文件中已存储了列名行) (若不手动指定,header参数默认为0)
# 未设置`index_col=0`,因为原xlsx_path文件中未存储索引列。因此,这里会自动生成从0开始的整数序列。
# `dtype={'col_1': 'str'}`: int64 -> str 根据情况,自行设置
df = pd.read_excel(xlsx_path, sheet_name='Sheet_1', engine='openpyxl', header=0, dtype={'col_1': 'str'})
print(df)
print('done')
1
2
3
4
5
6
7
8
9
10
11
def read_change_xlsx_1():
"""
打开.xlsx文件的任意一个Sheet页,对df进行修改,然后再次存入同样的.xlsx路径
无论原.xlsx文件中是否存在新指定的Sheet页,原.xlsx文件都会被全面覆盖。
即,完全覆盖,并重新创建了一个新的.xlsx文件,只是命名相同而已。
"""
xlsx_path = Path("./tmp_data/test.xlsx")
df = pd.read_excel(xlsx_path, sheet_name='Sheet_1', engine='openpyxl', header=0, dtype={'col_1': 'str'})
df['col_3'] = 'new_add'
df.to_excel(xlsx_path, sheet_name='Sheet_4', index=False, header=True, engine='openpyxl')
print('done')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def read_change_xlsx_2():
"""
打开.xlsx文件的任意一个Sheet页,对df进行修改,然后再次存入同样的.xlsx路径
"""
xlsx_path = Path("./tmp_data/test.xlsx")
df = pd.read_excel(xlsx_path, sheet_name='Sheet_1', engine='openpyxl', header=0, dtype={'col_1': 'str'})
df['col_3'] = 'new_add'

# 修改后的df存入到一个新的Sheet页,原Sheet页内容不变
with pd.ExcelWriter(str(xlsx_path), engine='openpyxl', mode='a', if_sheet_exists='new') as writer:
df.to_excel(writer, sheet_name='Sheet_2', index=False, header=True)

# 用修改后的df替换已存在的Sheet页,若指定的sheet_name不存在,则新建一个Sheet页(功能与new一致)
with pd.ExcelWriter(str(xlsx_path), engine='openpyxl', mode='a', if_sheet_exists='replace') as writer:
df.to_excel(writer, sheet_name='Sheet_1', index=False, header=True)

print('done')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def write_w_xlsx():
xlsx_path = Path("./tmp_data/test.xlsx")
if xlsx_path.exists():
xlsx_path.unlink()
xlsx_path.touch(exist_ok=False)

df = pd.DataFrame(columns=['col_1', 'col_2']) # 创建一个空的DataFrame,但指定列名
df.loc[0] = ['0', 'aaa']
df.loc[1] = ['1', 'bbb']
df.loc[2] = ['0', 'ccc']

columns_order = ['col_2', 'col_1']
# `index=False`: 不要将df每行的索引,作为第一列写入文件。(即不保留行索引)
# `header=True`: 将df每列的列名,作为第一行写入文件。(即保留列名)
# `columns=columns_order`: 仅将这两个列的数据写入文件,且指定列名顺序
df.to_excel(xlsx_path, sheet_name='Sheet_1', index=False, header=True, columns=columns_order, engine='openpyxl')
print('done')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
def write_a_xlsx():
"""
原始内容在Sheet_1,追加内容在Sheet_2,Sheet_3
即追加的是新的Sheet页
"""
xlsx_path = Path("./tmp_data/test.xlsx")
if xlsx_path.exists():
xlsx_path.unlink()
xlsx_path.touch(exist_ok=False)

column_order = ['col_1', 'col_2']
df_1 = pd.DataFrame(columns=['col_1', 'col_2'])
df_1.loc[0] = ['0', 'aaa']
df_1.loc[1] = ['1', 'bbb']
df_1.loc[2] = ['0', 'ccc']
df_1.to_excel(xlsx_path, sheet_name='Sheet_1', index=False, header=True, columns=column_order, engine='openpyxl')

df_2 = pd.DataFrame(columns=['col_1', 'col_2'])
df_2.loc[0] = ['0', 'ddd']
df_2.loc[1] = ['1', 'eee']
df_2.loc[2] = ['0', 'fff']

df_3 = pd.DataFrame(columns=['col_1', 'col_2'])
df_3.loc[0] = ['1', 'ggg']
df_3.loc[1] = ['0', 'hhh']
df_3.loc[2] = ['1', 'iii']

df_4 = pd.DataFrame(columns=['col_1', 'col_2'])
df_4.loc[0] = ['38', 'jjj']
df_4.loc[1] = ['33', 'kkk']

# `if_sheet_exists`参数:
# `error`: 默认,如果Sheet页已存在,抛出错误
# `new`: 创建一个新的Sheet页,若指定的新Sheet页名称已存在,则会自动为新Sheet页名称添加一个序号后缀再创建
# `replace`: 替换指定Sheet页;若指定Sheet页不存在,则新增指定Sheet页,且原Sheet页不受影响(与`new`结果一致)
# `overlay`: 覆盖已存在的Sheet页,覆盖能覆盖到的内容,覆盖不到的地方保留原数据;若指定Sheet页不存在,则新增指定Sheet页,且原Sheet页不受影响(与`new`结果一致)
with pd.ExcelWriter(str(xlsx_path), engine='openpyxl', mode='a', if_sheet_exists='new') as writer:
df_2.to_excel(writer, sheet_name='Sheet_2', index=False, header=True, columns=column_order)

with pd.ExcelWriter(str(xlsx_path), engine='openpyxl', mode='a', if_sheet_exists='replace') as writer:
df_3.to_excel(writer, sheet_name='Sheet_1', index=False, header=True, columns=column_order)

with pd.ExcelWriter(str(xlsx_path), engine='openpyxl', mode='a', if_sheet_exists='overlay') as writer:
df_4.to_excel(writer, sheet_name='Sheet_1', index=False, header=True, columns=column_order)

print('done')

dataframe基础操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
def df_operation_1():
# 创建一个空df,但可指定列名
df = pd.DataFrame(columns=['col_1', 'col_2', 'col_3'])

###################################
# 新增行数据、列数据
###################################
# df新增行数据,`.loc[n]`是行索引,可以不连续
df.loc[0] = ['1321', 'ssd', '中文文本']
df.loc[1] = ['87646', 'retrtre', '德玛西亚']
df.loc[2] = ['87433', 'gthh', '诺克萨斯']
# df新增列数据
# df['col_4'] = [23, 24, 25]

###################################
# 删除行数据、列数据
###################################
# df删除行数据,并创建新的独立副本
# new_df = df.drop(1, axis=0)
# df删除列数据,并创建新的独立副本
# new_df = df.drop('col_2', axis=1)
# 在原始df上删除行数据,返回None
# df.drop(1, axis=0, inplace=True)
# 在原始df上删除列数据,返回None
# df.drop('col_2', axis=1, inplace=True)

###################################
# 拼接
###################################
# df_2 = df.drop(1, axis=0)
# df_3 = df.drop('col_2', axis=1)
# 行拼接
# res_row = pd.concat([df, df_2], axis=0)
# 列拼接
# res_col = pd.concat([df, df_3], axis=1)

###################################
# `.loc`与`.iloc`对区间的管控不同
###################################
# `.loc`: 第一个参数指定行的选取范围(注意: 是左右闭区间!!!),第二个参数通过列名进行列的选取
# df_1 = df.loc[0:1, ['col_1', 'col_3']]
# df_2 = df.loc[:, ['col_1', 'col_3']]

# `.iloc`: 第一个参数指定行的选取范围(注意: 是左闭右开区间!!!),第二个参数通过列索引进行列的选取(从0开始)
# df_3 = df.iloc[0:1, [0, 2]]
# df_4 = df.iloc[:, [0, 2]]

# 仅筛选行,列全选
# df_5 = df.loc[1]
# df_6 = df.loc[:]

# 通过条件选择子集,并对其进行赋值修改,需注意是否是在原始DataFrame上进行的操作
# 错误举例:
# `df_train['label'] = 0`,
# `df_train[df_train['llm_label'] == 'y']['label'] = 1`
# 是无效的,因为`df_train[df_train['llm_label'] == 'y']`创建了一个新的DataFrame视图,而不是直接在原始DataFrame上操作
# 为正确进行赋值修改,应使用`.loc`方法,确保在原始DataFrame上操作
# df['col_4'] = 0
# df.loc[df['col_1'] == '1321', 'col_4'] = 1

# 创建副本,对副本操作不会影响原始DataFrame
# df_copy = df[df['col_1'] == '1321'].copy()
# df_copy['col_4'] = 0

# 多条件筛选,使用`&`, `|`等,且不同条件用`()`括起来
# df_7 = df[(df['col_1'] == '1321') | (df['col_3'] == '诺克萨斯')]

# 获取行索引
# index = df.index
# 获取列名
# column = df.columns

###################################
# 按行遍历
###################################
# 遍历某几个列的数据
# for col_1, col_3 in zip(df['col_1'], df['col_3']):
# print(col_1, col_3)
# 遍历所有列的数据
# 方法1: `iterrows()`返回每行的索引以及行数据
# for index, row in df.iterrows():
# print(row)
# 方法2: `itertuples()`方法为DataFrame每一行返回一个命名tuple
# for row in df.itertuples():
# print(row)
# 方法3: `apply()`方法在DataFrame的每一行/列上应用一个函数。(即遍历每一行/列,每一行/列都应用process方法) (返回新的独立副本)
# 注意,这里axis与其他情况不同,axis=0是按列;axis=1是按行
# def process(row):
# print(row)
# new_df = df.apply(process, axis=1)

###################################
# 按列遍历
###################################
# 方法1: 使用for循环遍历列名,使用列名访问每一列数据
# for column in df:
# print(column)
# print(df[column])
# 方法2: `apply()`方法
# def process(column):
# print(column)
# new_df = df.apply(process, axis=0)


# -----------------------------------------------------------------
# df.loc[3] = [np.NAN, 'tmp', '包含空值的']
# df.loc[4] = ['889', np.NAN, '也是有空值']
# df.loc[5] = np.NAN
# df['col_5'] = np.NAN

###################################
# 删除NAN数据
###################################
# 删除包含任意NAN的行,返回新的df
# new_df = df.dropna(axis=0, how='any')
# 删除包含任意NAN的列,返回新的df
# new_df = df.dropna(axis=1, how='any')
# 删除所有元素都是NAN的行,返回新的df
# new_df = df.dropna(axis=0, how='all')
# 删除所有元素都是NAN的列,返回新的df
# new_df = df.dropna(axis=1, how='all')

###################################
# 数据替换
###################################
# 使用value的值,替换to_replace的值,返回新的df
# new_df = df.replace(to_replace='889', value='777777777')

###################################
# np.NAN检查
###################################
# 返回元素均为bool True/False的新df。
# (原df中np.NAN位置为True,非np.NAN位置为False)
# new_df = pd.isnull(df)

###################################
# 类型替换
###################################
# 将 list,tuple,1-d array,Series ,转为数值类型
# errors参数:
# 'raise': (默认)无效解析将引发异常
# 'coerce': 无效解析将被置为np.NAN
# 'ignore': 无效解析将返回输入
# new_df = pd.to_numeric(df.loc[1], errors='coerce')
# 将dataframe或Series中,数值类型转为str
# new_df = df.astype(str)
# new_df = df.loc[1].astype(str)
# df转numpy
# numpy_array = df.to_numpy()
# numpy_array = df.values

###################################
# apply方法,使用lambda函数 (返回新的独立副本)
###################################
# df_tmp = pd.DataFrame({
# 'A': [1, 2, 3],
# 'B': [4, 5, 6]
# })
# df_tmp_col = df_tmp.apply(lambda x: x * x, axis=0) # 与其他不同,apply() axis=0 对每列进行遍历
# df_tmp_row = df_tmp.apply(lambda x: x * x, axis=1) # 与其他不同,apply() axis=1 对每行进行遍历
# 对单列使用lambda
# df_tmp['A'] = df_tmp['A'].apply(lambda x: x * 2)

###################################
# 列重命名
###################################
# df.rename(columns={df.columns[1]: 'col_2_new'}, inplace=True)

###################################
# 单列去重 (返回array)
###################################
# df_tmp = pd.DataFrame({
# 'A': [1, 1, 2]
# })
# array_res = df_tmp['A'].unique()
# print(array_res)

###################################
# 统计信息
###################################
df_tmp = pd.DataFrame(columns=['A', 'B', 'C'])
df_tmp.loc[0] = [1, 2, 3]
df_tmp.loc[1] = [6, 5, 4]
df_tmp.loc[2] = [8, 9, 7]
print(df_tmp)
print('*'*40)

# print(df_tmp.sum(axis=1)) # 各行/列的和,axis=1为行
# print(df_tmp.min(axis=1)) # 各行/列的min,axis=1为行
# print(df_tmp.max(axis=1)) # 各行/列的max,axis=1为行
# print(df_tmp.idxmin(axis=1)) # 各行/列的min的idx,axis=1为行
# print(df_tmp.idxmax(axis=1)) # 各行/列的max的idx,axis=1为行
# print(df_tmp.mean(axis=1)) # 各行/列的均值,axis=1为行
# print(df_tmp['A'].mean()) # 对单列操作
# print(df_tmp.loc[0].mean()) # 对单行操作

print('here')

numpy

npy

1
2
3
4
5
6
def read_npy():
# 单个数组
npy_path = Path("./arr_tmp.npy")
loaded_arr_tmp = np.load(str(npy_path))
print(loaded_arr_tmp)
print('done')
1
2
3
4
5
6
7
8
9
def write_npy():
# 单个数组
npy_path = Path("./arr_tmp.npy")
if npy_path.exists():
npy_path.unlink()

arr_tmp = np.array([1, 2, 3, 4, 5, 6])
np.save(str(npy_path), arr_tmp)
print('done')

npz

1
2
3
4
5
6
7
8
def read_npz():
# 多个数组
npz_path = Path("./arr_tmp.npz")
loaded_arr = np.load(str(npz_path))
print(f"arr_1: {loaded_arr['arr_1']}")
print(f"arr_2: {loaded_arr['arr_2']}")
print(f"arr_3: {loaded_arr['arr_3']}")
print('done')
1
2
3
4
5
6
7
8
9
10
11
12
def write_npz():
# 多个数组
npz_path = Path("./arr_tmp.npz")
if npz_path.exists():
npz_path.unlink()

arr_1 = np.array([1, 2, 3, 4, 5])
arr_2 = np.array([6, 7, 8, 9, 10])
arr_3 = np.array([11, 12, 13, 14, 15])

np.savez(str(npz_path), arr_1=arr_1, arr_2=arr_2, arr_3=arr_3)
print('done')

txt

1
2
3
4
5
def read_txt():
txt_path = Path("./arr_tmp.txt")
loaded_arr = np.loadtxt(str(txt_path))
print(loaded_arr)
print('done')
1
2
3
4
5
6
7
8
9
10
def write_txt():
txt_path = Path("./arr_tmp.txt")
if txt_path.exists():
txt_path.unlink()

arr = np.array([[1.862, 2.555, 3.2452, 4.2782], [5.2785, 6.27825, 7.287532, 8.25278]])
# fmt,指定元素数据格式。'%d': 整数; '%f': 浮点数; '%.2f': 浮点数,保留两位小数; '%e': 科学计数法。
# newline,指定如何换行
np.savetxt(str(txt_path), arr, fmt="%f", newline='\n')
print('done')

numpy基础操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import numpy as np


# 创建一维、二维数组
res_0 = np.array([1, 2, 3, 4, 5])

np.asarray([[1, 2, 3], [4, 5, 6]])

np.arange(start, stop, step, dtype)

# 生成指定维度的[0, 1)之间的随机浮点数
np.random.rand(4, 3) # np.random.rand 等价于 np.random.random

# 生成指定维度的随机浮点数,服从正太分布
np.random.randn(2, 4)

# 生成size维度的随机整数,范围[low, high),dtype默认为int,服从均匀分布
np.random.randint(low=1, high=10, size=(3, 4), dtype='I')

# 生成size维度的随机浮点数,范围[low, high),服从均匀分布
np.random.uniform(low=1.0, high=10.0, size=(3, 4))

# 其他np.random操作,详见"py常用数据结构-常用操作"


res_1 = np.array([[1, 2, 3], [4, 5, 6]])
# res_1.ndim int 2
# res_1.shape tuple (2, 3)
# res_1.size int 6
# res_1.min() int 1
# res_1.max() int 6
# res_1.argmin() int 0 # 最小值的索引
# res_1.argmax() int 5 # 最大值的索引
# res_1.dtype int32


# 计算总和
res_sum = np.sum(res_1)
res_sum_col = np.sum(res_1, axis=0) # 每列的总和
res_sum_row = np.sum(res_1, axis=1) # 每行的总和
res_sum_condition = np.sum(res_1 == 1) # True=1,False=0


# numpy转list
res_1_list = res_1.tolist()


# 元素类型转换
res_1.astype(numpy.float32)


# 初始化数组
np.empty((2, 3)) # 随机初始化
np.zeros((2, 3))
np.ones((2, 3))
np.eye(3) # 二维单位对角矩阵


# 继普通索引外,布尔索引
res_1 > 3 # ndarray: (2, 3) [[False, False, False], [True, True, True]]
res_1[res_1 > 3] # ndarray: (3,) [4, 5, 6]


# 条件筛选
# 不提供x,y,返回满足条件的索引
arr = np.array([1, 2, 3, 4, 5, 6])
res_idx = np.where(arr > 3)

# 提供x,y,从x,y中选择元素。满足条件选择x中元素,不满足条件选择y中元素
condition = np.array([True, False, True, False, True])
x = np.array([1, 2, 3, 4, 5])
y = np.array([6, 7, 8, 9, 10])
res = np.where(condition, x, y)


# 修改数组形状
tmp = np.reshape(np.arange(start=0, stop=9, step=1), (3, -1))


# 数组铺平,返回一个迭代器
tmp = np.array([[1, 2, 3], [4, 5, 6]])
for ele in tmp.flat:
print(ele)

# 数组铺平,返回一维数组。(返回新的拷贝,修改不影响原数组)
tmp_flatten = np.array([[1, 2, 3], [4, 5, 6]]).flatten()


# 数组转置
np.array([[1, 2, 3], [4, 5, 6]]).T


# 升维
arr = np.array([1, 2, 3])
arr_expand = np.expand_dims(arr, axis=0)

# 降维
arr_squeeze = np.squeeze(arr_expand, axis=0)


# 数组拼接,不新增维度
tmp_a = np.array([1, 2, 3])
tmp_b = np.array([4, 5, 6])
concated_res = np.concatenate((tmp_a, tmp_b), axis=0)

# 数组堆叠,新增额外维度
stack_res = np.stack((tmp_a, tmp_b), axis=0)


# 按特定维度分割数组
tmp = np.array([[1, 2, 3], [4, 5, 6]])
tmp_split = np.split(tmp, indices_or_sections=3, axis=1) # indices_or_sections,均分子数组个数


# 数组插入 (在末尾插入) 不会修改原始数组,而是返回一个新的数组
# axis指定在哪个轴插入。默认为None,此时数组会被展平
tmp = np.array([[1, 2, 3], [4, 5, 6]])
tmp_append = np.append(tmp, [[7, 8, 9]], axis=0)


# 数组去重
tmp = np.array([[1, 2, 2], [4, 2, 6]])
tmp_unique = np.unique(tmp)