(Python)Pandas 常用操作

包含以下內(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í)用的:

  1. 設(shè)置索引: index_col=0 設(shè)置第一列為索引,這樣就不會(huì)讀了之后,又加一個(gè)索引
  2. 只讀取某些列: usecols = ['colname1', 'colname2'] :只讀取其中的某些列
  3. 設(shè)置數(shù)據(jù)類(lèi)型:dtype = {'colname1': int, 'colname2': str} :按類(lèi)型讀取這些列,注意,如果類(lèi)型不匹配,會(huì)報(bào)錯(cuò)
  4. 錯(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)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容