包含以下內(nèi)容:
1 數(shù)據(jù)讀寫(xiě)
1.1 數(shù)據(jù)讀取
讀取.csv或者讀取.tsv文件:
import pandas as pd
result_df = pd.read_csv("filename.csv") # csv
result_df = pd.read_csv("filename.tsv", sep='\t'). # tsv
在使用read_csv時(shí),有一些參數(shù),挺實(shí)用的:
- 設(shè)置索引: index_col=0 設(shè)置第一列為索引,這樣就不會(huì)讀了之后,又加一個(gè)索引
- 只讀取某些列: usecols = ['colname1', 'colname2'] :只讀取其中的某些列
- 設(shè)置數(shù)據(jù)類(lèi)型:dtype = {'colname1': int, 'colname2': str} :按類(lèi)型讀取這些列,注意,如果類(lèi)型不匹配,會(huì)報(bào)錯(cuò)
- 錯(cuò)誤處理:error_bad_lines = False :對(duì)不符合csv規(guī)范的行,跳過(guò)
如果想知道哪些字段為空,記得:
test_df = test_df.fillna("")
之后取數(shù)據(jù)判斷是否為空:
if test_df.iloc[i]["col_name"].strip() == "":
因?yàn)槿绻悴贿@樣填充的話(huà), 原本空的單元格讀取后會(huì)是float類(lèi)型的nan比如
print(data.iloc[0]['note']) # nan
print(type(data.iloc[0]['note'])) # <class 'float'>
# if data.iloc[0]['note'] # 這樣是True, 也就是你沒(méi)法用if進(jìn)行判斷
合理的判斷方式是:
result = data.iloc[0]['note']
print(math.isnan(result)) # True
print(pd.isna(result)) # True
1.1 寫(xiě)數(shù)據(jù)
寫(xiě)入csv中文亂碼,解決方案:
result_df.to_csv("xxx.csv", encoding="utf_8_sig")
寫(xiě)入csv時(shí),不寫(xiě)入索引:
result_df.to_csv("xxx.csv", index=None)
2 數(shù)據(jù)預(yù)處理
2.1 處理數(shù)據(jù)類(lèi)型錯(cuò)誤
數(shù)據(jù)類(lèi)型錯(cuò)誤比如你的某一列"age"表示的是年齡,但是其中有些數(shù)據(jù)錯(cuò)誤,含有字母而無(wú)法轉(zhuǎn)變?yōu)檎汀<聪旅孢@行代碼報(bào)錯(cuò):
result_df = pd.read_csv("filename.csv", dtype={'age': int},)
這時(shí),需要不帶類(lèi)型的讀取這一列數(shù)據(jù),然后使用pd.to_numeric處理:
result_df = pd.read_csv("filename.csv", )
result_df.age = pd.to_numeric(result_df.age, errors='coerce', )
# 其中,errors='coerce' results in NaN for entries that can't be converted
result_df = result_df[result_df.age.notnull()]. # 只取不為空的部分
# 因?yàn)檫@里是浮點(diǎn)型,你可以舍棄精度,轉(zhuǎn)為整型:
result_df['age'] = result_df['age'].astype(int)
# 可以取多行同時(shí)不為空的部分:
# result_df = result_df[result_df.age.notnull() & result.height.notnull()]
2.2 排序-按照某些列排序:
res = df.sort_values(by=['A', 'B'], ascending=[True, True])
注意排序后,index并沒(méi)有變,也就是說(shuō),你按index取數(shù)據(jù),res.loc[i, :],一個(gè)遞增的i取出的數(shù)據(jù)并不是遞增的。
所以一般建議,排序后,重排index:
res = res.reset_index()
2.3 列名
2.3.1 列名的獲取與修改
打印列名 、 獲取每一列的數(shù)據(jù)類(lèi)型
print(df.columns)
print(df.dtypes)
修改列名:
df.rename(columns={'old_name1':'new_name1', 'old_name2':'new_name2'},inplace=True)
# 不用賦值,用了 inplace=True,意味著df的列名就在原來(lái)的變量上改了
# 也可以直接給列名整體賦值
df.columns=['new_name1','new_name2','new_name3']
2.3.2 根據(jù)列名取數(shù)據(jù),增加列
根據(jù)列名取某幾列的數(shù)據(jù):
如取出'col1', 'col2', 'col3'這三列的數(shù)據(jù),形成一個(gè)新的DataFrame
df = df.loc[:, ['col1', 'col2', 'col3',]]
這里注意loc和iloc的區(qū)別,閑話(huà)少敘,直接上結(jié)論:
建議:取數(shù)據(jù)用iloc,改數(shù)據(jù)用loc:
df.loc[i, 'col_name'] = 6 # 用這種方式給行索引為i,'col_name'列的數(shù)據(jù)賦值
df.loc[i, 'col_name'] = df.iloc[j]['col_name2'] # 取出另一個(gè)數(shù)據(jù),用來(lái)賦值
這里需要注意的是loc中的i是索引,并不是第i行的意思。一般情況下二者是一致的,但是當(dāng)你取部分?jǐn)?shù)據(jù)的時(shí)候就會(huì)有問(wèn)題,比如你
df = df[100:200]
這樣取出第100-200個(gè)數(shù)據(jù),你的數(shù)據(jù)長(zhǎng)度是100,但是索引是100-200.
根據(jù)已有的列構(gòu)成新的列:
如你現(xiàn)在有一列表示日期,你想把年份單獨(dú)取出來(lái)構(gòu)成新的一列,然后統(tǒng)計(jì)不同年份的數(shù)據(jù)有多少:
# ’DATE’列的格式:06/18/2007 我們切片取[6:10]就是年份了
crime_df['year'] = crime_df['DATE'].str[6:10]
再比如,你希望有一個(gè)新的列,是另外幾個(gè)列的拼接:
注意這樣拼接,得轉(zhuǎn)化成str所以這里都用map處理了。
merged_df['group'] = merged_df['section'].map(str) + merged_df['ipc_class'].map(str) + merged_df['subclass'].map(str)
2.4 日期與時(shí)間-datetime的使用:
將一列(String)轉(zhuǎn)化成datetime格式:
# 假設(shè)原本的'dt'列是形如 “2020-12-01 04:34:22” 的字符串
df['dt'] = pd.to_datetime(df['dt'], format='%Y-%m-%d %H:%M:%S')
提取某段時(shí)間的數(shù)據(jù):
https://blog.csdn.net/caoxinjian423/article/details/113029894
https://blog.csdn.net/qq_38412868/article/details/107445068
上面這兩篇文章講的非常詳細(xì),下面我摘錄幾個(gè)常用的:
# 如下面這行,提取小時(shí)在16-23之間的數(shù)據(jù)
df= df[df['dt'].dt.hour.isin(np.arange(16, 24))]
# 獲取一月份到四月份的數(shù)據(jù):
df[df['dt'].dt.month.isin(np.arange(1, 5))]
# df['日期'].dt.weekday # 返回一周中的星期幾,0代表星期一,6代表星期天
2.5 拼接
最常用的:按某一列拼接,你的兩個(gè)df要有一個(gè)共同的列名:
result = pd.merge(left, right, on='colname')
3 數(shù)據(jù)修改、初始化
3.1 對(duì)某個(gè)元素的賦值與取值
賦值有多種方法,這里我推薦用loc給指定的單元賦值(使用同樣的方法,可以取出指定位置的值),不會(huì)報(bào)那個(gè)你沒(méi)copy的warning:
df.loc[index, 'COLNAME'] = VALUE
# index 索引,非常適用于外面套一個(gè)for循環(huán)的情況
# 'COLNAME':列名
# VALUE:值
3.2 往空的DataFrame里加?xùn)|西
先構(gòu)建一個(gè)空的DataFrame,然后一行一行往里面加?xùn)|西:
columns = ["col1", "col2", "col3"]. # 先把列明確定好
result_df = pd.DataFrame(columns=columns)
# 這種方式,你可以指定你插入的數(shù)據(jù)是哪些列的 ,如果是完整的一行,那就直接跟列名列表相等就好
df = df.append(pd.DataFrame([new_line], columns=columns))
2.3 構(gòu)造新的列
新增一列,并賦初值
test_df["new_col_name"] = 0
4 數(shù)據(jù)分析
4.1 單列統(tǒng)計(jì)
4.1.1 統(tǒng)計(jì)不同元素個(gè)數(shù)
統(tǒng)計(jì)某一列不同種類(lèi)的元素的個(gè)數(shù)。如:統(tǒng)計(jì)sex這一列(所得結(jié)果為男女各有多少人)
它的輸出結(jié)果是數(shù)目多的在前面,所以你也可以用它來(lái)查看著一列是否有重復(fù)項(xiàng)。
result = pd.value_counts(df['sex'])
print(result)
這個(gè)統(tǒng)計(jì)結(jié)果是Series類(lèi)型的如果要轉(zhuǎn)為DataFrame,要這樣做:
dict_result = {'col1':result.index,'col2':result.values}
df = pd.DataFrame(dict_result)
4.2 數(shù)據(jù)采樣
如:采樣200個(gè)數(shù)據(jù)
test_df.sample(200)