dataframe等常用操作


一、創建、取某列某行、刪除某列

import pandas as pd
lst=[2,3,5] #表示df的一行
df=pd.DataFrame(data=[lst,lst],columns=['col1','col2','col3']) #從列表生成DF
df=pd.DataFrame(data={'col1':[2]*2,'col2':[3]*2,'col3':[5]*2})#字典生成DF

df[['col1','col2']]#可以取出對第一、二列的數據
df[2:][['col1','col2']] #可以取出第2行到最后一行的第1、2列的數據

df.drop('col1',axis=1)#刪除第1列
df.drop(['col1','col2',axis=1])

pd.read_csv(file_path,header=None,index_col=0,encoding='utf-8',skiprows=2)  
#index_col表示設置第0列為index列,skiprows表示跳過前2行讀取數據,前2行即第[0,1]行。
#若index_col=False則表示index列為默認的另外的列

df.to_csv(path,index=False) #index=False表示保存的csv不帶index,否則默認情況下保存的csv是默認寫入index列的

df.to_hdf('data.h5','df')
pd.read_hdf('data.h5','df')#寫入讀取HDF5數據

 

二、對一列或者多列作運算

1. 利用map對一列作運算

df['col'] = df['col1'].map(lambda x: x**2)  #生成一列,是第1列的平方

2.利用apply對一列或多列作運算

df.index  = pd.date_range('20190101',periods=5) #將原來的index改成以日期為index
df['col'] = df.apply(lambda x:x['col1']*x['col2'], axis=1) #對'col'列改寫成'col1'列的對應行乘以'col2'列的對應行

 三、求滑動平均

df['MA'] = df['col'].rolling(window=3, center=False).mean() 

四、對列作向上或向下的平移變換

df = pd.DataFrame({'id':[1,1,1,2,2,3],'value':[1,2,3,4,5,6]})
df['value_shift'] = df.groupby('id')['value'].shift(1) #按id列分組,對value列進行平移變換,即都向下移動1行
df['value_shift_1'] = df.groupby('id')['value'].shift(-1) #按id列分組,對value列進行平移變換,即都向上移動1行
 
        

五、對列作標准化處理:

from sklearn import preprocessing
df = pd.DataFrame({'id':[1,1,1,2,2,3],'value1':[1,2,3,4,5,6],'value2':[1,3,4,3,7,2]})
value=df[['value1','value2']]
value_T=value.transpose() #value_T是array類型
scaler=preprocessing.StandardScaler().fit(value_T) #scaler是對行數據作標准化,所以對df的列數據應該將其轉置
value_T_scale = scaler.transform(value_T)
value_scale = value_T_scale.transpose()

#有時需要用到np.array的reshape:
y=df[['value']]    #y.shape=(6,1)
y=y.reshape(1,-1)  #y.shape=(1,6)
y=y.reshape(-1,1)  #y.shape=(6,1)
y=np.repeat(0,len(y)) #生成零矩陣

 六、對某列賦值

df = pd.DataFrame({'id':[1,1,1,2,2,3],'value':[1,2,3,4,5,6]})
value=[11,22,33]
df.loc[df.index[0:3],'value']=value
df.loc[df.index[0:3], 'value0']=value

七、 對list中多個重復的字符作頻數統計

lst=['a','a','a','b','c','c','b','e','f','a','a','c']
cnt = pd.Series(lst).value_counts()

 八、隨機抽樣

DataFrame.sample(n=None, frac=None, replace=False, weights=None, random_state=None, axis=None)
  • n:隨機抽取n行數據
  • frac:隨機抽取的比例
  • replace:True有放回抽樣;False不放回抽樣
  • random_state:隨機數種子生成器
  • axis:0按行抽取,1按列抽取

frac=1可將樣本作打亂處理

九、清洗數據

df[df.isnull()]
df[df.notnull()]
df.dropna()#將所有含有nan項的row刪除
df.dropna(axis=1,thresh=3) #將在列的方向上三個為NaN的項刪除
df.dropna(how='ALL')#將全部項都是nan的row刪除填充值
df.fillna(0)
df.fillna({1:0,2:0.5}) #對第一列nan值賦0,第二列賦值0.5
df.fillna(method='ffill') #在列方向上以前一個值作為值賦給NaN

十、數據篩選

聚合函數

groupby(df['支局_維護線'])
df.groupby('支局_維護線')['用戶標識'] #上面的簡單寫法
df.groupby('支局_維護線')['用戶標識'].agg([('ADSL','count')])#按支局進行匯總對用戶標識進行計數df,並將計數列的列名命名為ADSL

合並函數(類似SQL中的JOIN)

x=df[df['post_time'].isin(['2018-12-25'])]
y=pd.merge(df,x,left_on='username',right_on='username',how='inner',suffixes='_df','_x')#內連接,連接兩邊都有的值
#inner(內連接)、outer(外鏈接)、left(左連接)、right(右連接)
#suffixes表示連接的列如果屬於df就在其列名后面加'_df',否則會默認加為'_x','_y'
 
         
y=pd.merge(df,x,on='username')#內連接,連接兩邊都有的值
 

數據篩選

x=df[df['username'].str.contains(r'潮州*')] #使用正則表達式進行模糊匹配,*匹配0或無限次,?匹配0或1次

#使用DataFrame進行數據轉換
x['username'] = x['username'].str.replace()#replace的括號里使用正則表達式

十一、concat

pd.concat([df1,df2,df3])#默認axis=0,按行合並

 

pd.concat([df1,df4],axis=1)#按列合並

 

pd.concat([df1, df4], ignore_index=True)#忽略索引信息,重排索引0,1,2,3....

 

 pd.concat([df1, df4], axis=1, join=‘inner’)#內連接合並,join默認為outer外連接。

 

 pd.concat([df1,df2,df3],keys=[‘x’, ‘y’, ‘z’]) #合並時便於區分建立層次化索引

 

 

十二、刪除drop,替代replace

import pandas as pd
import numpy as np
df1=pd.DataFrame(np.random.randn(4,3),columns=["A","B","C"])
print(df1)
df2=df1.drop(["A"],axis=1,inplace=True)#inplace=True表示在原df上操作,不生成新的df;axis=1表示對列進行操作
print(df1)
print(df2)
df2=df1.drop(["B"],axis=1,inplace=False)#inplace=False表示不在原df上操作,生成新的df;axis=1表示對列進行操作
print(df1)
print(df2)

結果如下:

import pandas as pd
df1=pd.DataFrame({'country':['A','A','C','B','C'],'province':[1,2,1,2,3],'people':[2,4,6,7,1]})
print(df1)
country=df1['country'].value_counts()
to_remove=country[country<2].index
print(to_remove)
df1.replace(to_remove, np.nan, inplace=True) #inpace=True表示在原df上操作,不生產新的df
print(df1)

 

df1.replace({'A':'B','C':'E'}) #替換多個值
print(df1)

 

 

 

注、一些常用介紹

df.describe() #描述性統計(對數值型數據列而言)

df.dtypes #查看各行的數據格式
df['列名'].astype(int)#轉換某列的數據類型
res_df['T'] = res_df['T'].apply(int)
#切片操作 df.iloc[1:10] #獲取1-10行的數據 df.iloc[columns_index] #獲取列的數據 df.iloc[1:5,[1,2,5]]#獲取1,2,5列的1~5行數據 df[columns].drop_duplicates() #剔除重復行數據 df.iloc[1:5,[1,2,5]]=1#所選位置數據替換為1 #使用DataFrame篩選數據(類似SQL中的WHERE) df['post_time'].isin(['2018-12-25']) #使用isin對數據進行篩選,返回行索引以及每行篩選的結果,若匹配則返回ture df[df['post_time'].isin(['2018-12-25'])] #獲取匹配結果為ture的行 from datetime import datetime x='2018-12-31 17:51:33' print(datetime.strptime(x,"%Y-%m-%d %H:%M:%S"))#將時間字符串解析為時間元組 x=datetime.strptime(x,"%Y-%m-%d %H:%M:%S") print(x.strftime("%Y-%m-%d")) #將時間元組轉化成時間字符串

 

 當某csv文件打開有錯誤時,可以嘗試:

df=pd.read_csv('../data/train.csv',header=None,index_col=None,error_bad_lines=False) #跳過出現錯誤的行

 

按照某列和某列來做頻數統計(適用於屬性數據),類似R語言中的table: 

data.groupby(['post_time', 'senti_label']).size()

 

 

按照某列來對某列做j簡單的運算

data.groupby(['post_time'])['senti_label'].sum() #統計每一天的數據

gubaData.groupby('Date')['read_number'].max()
#按照日期'Date'列統計‘read_number’的最大值

 

 按照索引合並兩個DF:

x=pd.merge(df,sentiD,left_index=True,right_index=True,how='inner')
df = pd.merge(df1, df2, how = 'left', left_index = True, right_index = True) #兩者有相同的index,且要將df2合並到df1中

 

在array后面添加元素:

d=np.array([1,2,3])
np.append(d,[4,5])  #array([1, 2, 3, 4, 5])
np.concatenate([d,[9,8]]) #array([1, 2, 3, 9, 8])

 

刪除某列例如A列中的含有nan的行

df.drop(df[np.isnan(df['A'])].index, inplace=True)

 

當有兩個df,兩個df的列名有的相同,有的不相同,需要取其都具有的列名的名稱

#首先將兩個df的列名取出來放在類似下面的x1,x2中;再如下方式取其共同的元素
x1=pd.DataFrame({'x':[1,2,3] },index=[1,2,3]);  x2=pd.DataFrame({'x':[4,3,5]},index=[3,4,5])
print(x1.index.difference(x2.index))  #  取不屬於X2.index的 X1.index 中的元素
print(x1.index.difference(x1.index.difference(x2.index)))  #    取x1.index和X2.index都包含的元素

 

取train和valid的一種方式:

x1=pd.DataFrame({'x':range(10)})
t = x1.sample(7,random_state=7)
v = x1[~x1['x'].isin(t['x'])]  # ~表示非,則取x1['x']中  不屬於t['x']  的元素對應的x1數據
print(t)
print(v)

  

 取train中非’class‘的其他所有列:

train[train.columns.difference(['class'])] 

 具有相同列的兩個df按照行合並起來:

df1.append(df2)

 刪除相同行

x=pd.DataFrame({'a':[1,1,2,3],'b':[2,2,2,4]})
print(x,'\n')

x=x.drop_duplicates()   #去掉重復的行
print(x)

 巧用map

x=pd.DataFrame({'a':[1,2,3],'b':[4,5,6]})
x['sum']=list(map(lambda a,b:a+b,x['a'],x['b']))
print(x)

 

指數滑動平均:

cc=pd.DataFrame({'A':[1,2,3,4,5,6,7,8,9,10]})
cc.ewm(span=3).mean()

 

 由上例看一下如何計算的:span=3,adjust默認為True,

 

 

 則alpha=2/(3+1)=0.5;計算上例中cc.index=2的指數平均值為:

 

 當adjust=False時,

 zip,lambda,map:

zip接受多個序列作為參數 

lambda定義一個簡單函數,實現簡化代碼的功能

map把函數和參數綁定在一起

a=[1,1,1]
b=[2,2,2]
c=[3,3,3]
abc=zip(a,b,c)
# print(list(abc))
for i,j,k in abc:
    print(i,j,k)

fun=lambda x,y:x+y
print(fun(1,2))

list(map(fun,[1,2,3],[3,4,5]))

 

 python中沒有 “condition ? value1 : value2 ”三目操作符,但是可以如下簡潔操作ifelse

x="Yes" if True else "No"
print(x)
x="Yes" if False else "No"
print(x)

 

 

 

 

 

參考:

 

后續再補充。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM