本文僅用于記錄日常使用sklearn、numpy、pandas過程中使用到的一些小函數,方便日后復用。
numpy 和 pandas 設置在print輸出時不使用科學計數法
import pandas as pd
import numpy as np
np.set_printoptions(precision=3, suppress=True)
np.set_printoptions(formatter={'float': '{: 0.3f}'.format})
pd.set_option('precision', 5) #設置精度
pd.set_option('display.float_format', lambda x: '%.5f' % x) #為了直觀的顯示數字,不采用科學計數法
# jupyter notebook中設置交互式輸出
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
#顯示所有列
pd.set_option('display.max_columns', None)
#顯示所有行
pd.set_option('display.max_rows', 500)
#設置value的顯示長度為100,默認為50
pd.set_option('max_colwidth',100)
pytorch 非科學計數法輸出
# pytorch 非科學計數法輸出
import torch
torch.set_printoptions(
precision=2, # 精度,保留小數點后幾位,默認4
threshold=1000,
edgeitems=3,
linewidth=150, # 每行最多顯示的字符數,默認80,超過則換行顯示
profile=None,
sci_mode=False # 用科學技術法顯示數據,默認True
)
1、如何合并一個稀疏矩陣和一個稠密矩陣?
此問題背景是使用sklearn生成tfidf特征時是一個稀疏特征矩陣,但是有時候還需要考慮加入其他特征,這些特征常常是稠密矩陣(pandas其他列)。
from scipy import sparse
import numpy as np
A = sparse.csr_matrix([[1,0,0],[0,1,0]])
B = np.array([1,2])
# 合并為稠密矩陣
np.column_stack((A.A, B))
# 輸出
array([[1, 0, 0, 1],
[0, 1, 0, 2]], dtype=int64)
# 合并為稀疏矩陣
sparse.hstack((A,sparse.csr_matrix(B).T))
# 輸出
<2x4 sparse matrix of type '<class 'numpy.int64'>'
with 4 stored elements in COOrdinate format>
sparse.hstack((A,sparse.csr_matrix(B).T)).toarray()
# 輸出
array([[1, 0, 0, 1],
[0, 1, 0, 2]], dtype=int64)
2、sklearn labelencoder如何處理OOV問題?
在pyspark中,stringIndex可以非常方便的處理OOV問題——'skip'或者'keep'。
但是sklearn的labelencoder并沒有這種功能。我們需要自己來處理OOV問題。
from sklearn.preprocessing import LabelEncoder
le = preprocessing.LabelEncoder()
le.fit(X)
le_dict = dict(zip(le.classes_, le.transform(le.classes_)))
df[your_col].apply(lambda x: le_dict.get(x, <unknown_value>))
參考:https://stackoverflow.com/questions/21057621/sklearn-labelencoder-with-never-seen-before-values
3、pandas groupby后如何根據某一列的值對group內的數據進行排序并獲取top n行?
樣例數據如下:
df1.groupby(["平臺","站點","媒體"]).apply(lambda x :
x.sort_values(by = "計費收入(精度保留)", ascending = False).head(5).reset_index(drop = True))
輸出如下:
根據多個字符串來過濾DataFrame行
# 某列的值包含多個字符串中的一個
df[df["col"].str.contains("a|b|c")]
# 某列的值在某個字符串集合中
df[df["col"].isin(["a", "b", "c")]
多層索引時如何根據索引來進行過濾行
通過df.index.get_level_values(n)
來進行過濾即可, 如
df[df.index.get_level_values(0).isin(MEDIA_TAGS)]
簡單的pandas apply加速替換的方法
%timeit list(map(divide, df['A'], df['B'])) # 43.9 ms
%timeit np.vectorize(divide)(df['A'], df['B']) # 48.1 ms
%timeit [divide(a, b) for a, b in zip(df['A'], df['B'])] # 49.4 ms
%timeit [divide(a, b) for a, b in df[['A', 'B']].itertuples(index=False)] # 112 ms
%timeit df.apply(lambda row: divide(*row), axis=1, raw=True) # 760 ms
%timeit df.apply(lambda row: divide(row['A'], row['B']), axis=1) # 4.83 s
%timeit [divide(row['A'], row['B']) for _, row in df[['A', 'B']].iterrows()] # 11.6 s
多層索引降為單層索引
# 方法1,合并多層索引的名稱
df.columns=["_".join(x) for x in df.columns.ravel()]
# 方法2,直接drop多層索引,若不止兩層可進行多次drop
df.columns=df.columns.droplevel(1)