程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

pandas筆記

編輯:Python

1. Series基礎

1.1. 創建Series

  • 從字典創建
prices = {'apple':4.99,
  'banana':1.99,
  'orange':3.99,
  'grapes':0.99}
ser = pd.Series(prices)
  • 從標量創建
ser = pd.Series(2,index = range(0,5))

1.1.1. 使用字母索引

ser = pd.Series(range(1,15,3),index=[x for x in 'abcde'])

1.1.2. 隨機數序列

import random
ser = pd.Series(random.sample(range(100),6))

1.1.3. 對Series進行命名

import pandas as pd
a =[1,3,5,7]
a = pd.Series(a,name ='JOE')
a = pd.DataFrame(a)

1.2. 提取元素

1.2.1. 使用比較

import pandas as pd
import random

x = random.sample(range(100),10)
print(x)
y = pd.Series(x)
print(y)
print("==============================")
print(y[y>40])

1.2.2. 使用列表索引

x=random.sample(range(100),10)
print(x)
y = pd.Series(x)
print(y[[2,0,1,2]])

1.2.3. 使用函數

def joe(x):
    return x +10
x = random.sample(range(100),10)
print('Data => ',x,'\n')
y = pd.Series(x)
print('Applying pow => \n' ,pow(y,2),'\n')
print('Applying joe => \n',joe(y))

1.2.4. 元素檢查

x = pd.Series(range(1,8),index=[x for x in 'abcdefg'])
print(x,'\n')
print('Is "j" in x? ','j' in x)
print('Is "d" in x? ', 'd' in x)

2. DataFrame基礎

2.1. 選擇定位

  • loc方法:通過行索引 "index" 中的具體值來取行數據(如取"Index"為"A"的行)
  • iloc方法:通過行號來取行數據(如取第二行的數據)
    • 選取某幾列: df.iloc[:,[0,3,5,1]]
  • 利用loc函數的時候,當index相同時,會將相同的Index全部提取出來,優點是:如果index是人名,數據框為所有人的數據,那麼我可以將某個人的多條數據提取出來分析;缺點是:如果index不具有特定意義,而且重復,那麼提取的數據需要進一步處理,可用.reset_index()函數重置index
    • 注意,此處設置索引時,直接 .set_index('XXX')不行,必須這樣: df = df.set_index('XXX')才能生效。
    • 或者,可以這樣: .set_index('XXX', inplace = True])
  • 使用點符號。
    • data.Area.head()
  • 如果選取的結果是dataframe,則列或行要表示成列表形式。
    • data[['column_name_1', 'column_name_2']]

2.1.1. 獲取DataFrame中分組最大值的索引

  • idxmax()可以獲取原df中最大值的索引
  • contb.groupby('cand_nm',as_index=False)[['contb_receipt_amt']].max().index()獲取的是生成的新df的索引(即從0開始)
  • contb.groupby('cand_nm')[['contb_receipt_amt']].max().index()獲取df是以 cand_nm為索引

綜上,想要獲取每個候選人獲取單筆獻金最大值的索引,只能用idxmax()方法。

但是這種方法有個缺陷,即只能找出其中一個最大捐贈者。如果一個候選人有多個相同額度的最大捐贈者,則這種方法行不通。

下面的方法,用groupby找出每個候選人最大的捐贈額,然後用候選人和捐贈額作為條件,找出相對應的行。

df_max_donation = pd.DataFrame()
s = contb.groupby('cand_nm')['contb_receipt_amt'].max()
for i in range(s.size):
    ex = 'cand_nm == "%s" & contb_receipt_amt == %f' % (s.index[i], s.values[i])
    # print(ex)
    df_max_donation = pd.concat([df_max_donation,contb.query(ex)],axis=0,)
display(df_max_donation)

應該還有一種方法,將s(Series)轉成dataframe,然後和contb進行join操作。 參見[[美國大選獻金分析#^805156]]

2.2. 刪除列

dt=data.drop("Area",axis=1,inplace=True)
  • axis=1,此操作影響列,即導致列的增加或減少
  • inplace=True,直接在原始 DataFrame 上編輯
  • 有關axis的用法可以參考[[#axis 的理解]]

2.3. 刪除行

df.drop([0, 1])
df.drop(index=[0, 1])

注意第一個參數為index,所以在以條件刪除行的時候要確認獲得條件篩選之後的index值作為參數。

import pandas as pd
import numpy as np
df = pd.DataFrame(np.arange(12).reshape(3,4), columns=['A', 'B', 'C', 'D'])
# df.drop(df[df['A']==4].index,inplace=True)
df.drop(df[df['A']==4].index,inplace=True)

2.4. 增加列或修改列

data.loc[data['id'] > 800, "first_name"] = "John"

這段代碼可以增加first_name列,如果first_name列已經存在,則會修改滿足條件的行的該列值。 增加列也可以用np.wherenp.select

另外,np.select也可以用來修改已經存在的某列的指定行的值,這種情況下,np.select修改的是整列的值,所以如果只想修改特定條件行的值,要注意修改default的值。

con = [abb_pop['state/region'] == 'PR', abb_pop['state/region'] == 'USA']
values = ['Puerto Rico', 'United States of America']

abb_pop['state'] = np.select(con, values, default=abb_pop['state'])

有關np.wherenp.select的解釋可以參考[[#np where 和 np select 再解釋]]

2.4.1. 問題

對於數值列,以億為單位。如果數值較小(小於0.1億),則轉化成以萬為單位,並加上萬“萬元”,否則,加上“億元”。

如何使用np.select()直接操作?

暫時只想到一個非直達的方法:

x = np.array([0.0001,0.03,0.1,0.9,1,4.3])
df = pd.DataFrame(x, columns = ['r_amt'])
condlist = [df['r_amt']<=0.1, df['r_amt']>0.1]
choicelist = [df['r_amt']*10000, df['r_amt']]
choicelist2 = ['萬元', '億元']

# 下面的寫法出錯。
# choicelist = [str(x) + '萬元', x**2]

df['amt'] = np.select(condlist, choicelist, None)
df['unit'] = np.select(condlist, choicelist2, None)
df['amt'] = df['amt'].astype('str')
df['all'] = df['amt'] + df['unit']
df

2.4.2. 某列字段拆分成新列

知識點:

  • apply的重要用法,可以將字符串分割之後的多列組合成pandas,方法就是 apply(Series, 1)
  • stack將拆散成的多列打散,變成多行。
  • 合並具有相同index的 DataFrameSeries ,可以用 join 。 具體可參見 IMDB - Analysis by Genres
s = dt['genres'].str.split('|').apply(Series, 1).stack()
s.index = s.index.droplevel(-1)
s.name = 'genres'
del dt['genres']
df = dt.join(s)

2.5. 重命名列

兩種方式重命名列:

  • 通過使用字典將舊名稱映射到新名稱進行重命名,格式為 {“old_column_name”: “new_column_name”, …};
    • data.rename(columns={"Area":"place_name"},inplace = False)
  • 通過提供更改列名稱的函數重命名。函數應用於每個列名稱。
    • data.rename(columns=str.lower)

2.6. 設置索引

df.set_index('country')

設置索引後可以方便地使用loc進行定位,也可以用join連接。

2.7. 設置列名

df.columns=['population','total GDP']

2.8. 對列進行數學操作

df['population'] =df['population']*1000

2.9. 統計列中不同元素出現的次數

df['xxx'].value_counts()

2.10. 自定義排序

from pandas.api.types import CategoricalDtype
cat_size_order = CategoricalDtype(
    ['浦東新區', '闵行區', '徐匯區', '松江區', '黃浦區', '普陀區', '嘉定區', '靜安區', '奉賢區', '楊浦區', '青浦區', '崇明區', '虹口區', '金山區', '寶山區', '長寧區', '全市'], 
    ordered=True
)
df['行政區'] = df['行政區'].astype(cat_size_order)

2.11. 後續學習stack和unstack

TO BE STUDIED...

參考鏈接:

https://www.cxyzjd.com/article/S_o_l_o_n/80917211

https://www.jianshu.com/p/8a859643f37e

https://blog.csdn.net/S_o_l_o_n/article/details/80917211

2.12. 數據分段處理

bins = [0,1,10,100,1000,10000,100000,1000000,10000000]
labels = pd.cut(contb_vs['contb_receipt_amt'],bins)
contb_vs['label'] = labels
contb_vs

3. 其他基礎

3.1. axis的理解

我的理解:axis = 0 可以理解為結果影響行,axis = 1 可以理解為結果影響列。也就是說,最終作用的結果是行減少了(增加了)還是列減少了(增加了)。

作用范圍作用效果axis = 0行增加或減少axis = 1列增加或減少

比如:

data.drop("Area",axis=1),列減少;

df.mean(axis=0),行減少;

df.apply(lambda x:x.max()-x.min()),默認axis = 0,行增加(或減少);

另外可以參考Ambiguity in Pandas Dataframe / Numpy Array "axis" definition

3.2. np.wherenp.select再解釋

df['hasimage'] = np.where(df['photos']!= '[]', True, False)
store_patterns = [
    (df['Store Name'].str.contains('Hy-Vee', case=False, regex=False), 'Hy-Vee'),
    (df['Store Name'].str.contains('Central City',
                                case=False,  regex=False), 'Central City'),
    (df['Store Name'].str.contains("Smokin' Joe's",
                                case=False,  regex=False), "Smokin' Joe's"),
    (df['Store Name'].str.contains('Walmart|Wal-Mart',
                                case=False), 'Wal-Mart')
]

store_criteria, store_values = zip(*store_patterns)
df['Store_Group_1'] = np.select(store_criteria, store_values, 'other')

3.3. 時間日期學習

TO BE STUDIED...

3.3.1. 數據重采樣

df.resample('M').first() 相關資源:pandas.DataFrame.resample、時間重采樣的間隔參數

3.3.2. pandas.Series.rolling

可以在求諸如“5日平均”數據時使用。 相關資源:pandas.Series.rolling

3.3.3. pd.to_datetime

doc: pd.to_datetime,注意format等參數。

3.3.4. 獲取月份

參考[[消費行為分析#獲取月份]] astype('datetime64[M]')可以將datetime格式的數據轉成月份,優點是datetime64格式,但是在顯示的時候會顯示成“1970-01-01”這樣的格式。

to_period('M')可以將datetime格式的數據轉成月份,而且可以顯示成“1970-01”這樣的格式。缺點是不是datetime64格式。

如果只想獲取單獨的月或年,可以這樣:

df['year'] = df.order_dt.dt.year
df['month'] = df.order_dt.dt.month

格式為int64

另注意,這裡只是要獲取月份,暫時並不是要以月份重取樣然後求和、技術等操作。如果想做數據重取樣,需要對order_dt設置索引。因為resample只能對DatetimeIndex, TimedeltaIndex or PeriodIndex格式的數據進行。

這裡有個resample的常見問題**TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'RangeIndex'**,

Stack Overflow上有個答案:

Convert column date to datetimes and add parameter on to resample:

df['date'] = pd.to_datetime(df['date'])
weekly_summary = df.story_point.resample('W', on='date').sum()

If need new column:

weekly_summary['weekly'] = df.story_point.resample('W', on='date').transform('sum')

Or create DatetimeIndex:

df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')
weekly_summary = df.story_point.resample('W').sum()

If need new column:

weekly_summary['weekly'] = df.story_point.resample('W').transform('sum')

3.4. mapapplyapplymaptransform用法

  • map: 針對 Series
  • apply:   - 針對 DataFramed的軸向做運算,也就是說對行或列做運算,不能對單個元素做運算。運算結果返回去重長度的 Series。   - 針對 Series的元素進行運算。
  • applymap: 針對 DataFrame的元素做運算。
  • transform: 運算結果返回原長度的 Series

3.4.1. map操作

  • Series的方法 計算每一種水果的平均價格
dic = {
    'item':['apple','banana','orange','banana','orange','apple'],
    'price':[4,3,3,2.5,4,2],
    'color':['red','yellow','yellow','green','green','green'],
    'weight':[12,20,50,30,20,44]
}

df = DataFrame(dic)
mean_price = df.groupby('item')['price'].mean().to_dict()
df['mean_price'] = df['item'].map(mean_price)

3.4.2. apply操作

  • DataFramed的方法, 返回去重長度的Series
  • 作用:可以將 DataFramed中的行或列數據進行某種形式的運算操作。
def func(s):
    s = s.sum()
    print(s)
df.apply(func)

3.4.3. transform操作

  • 返回原長度的 Series
  • 如果要用自定義函數增加新列或對原有列賦值,要用 transform
def my_mean(s):
    sum = 0
    for i in s:
        sum += i
    return sum / s.size
df.groupby('item')['price'].apply(my_mean)
## 結果:
# item 
# apple 3.00 
# banana 2.75 
# orange 3.50 
# Name: price, dtype: float64
df.groupby('item')['price'].transform(my_mean)
# 結果:
# 0    3.00
# 1    2.75
# 2    3.50
# 3    2.75
# 4    3.50
# 5    3.00
# Name: price, dtype: float64

3.4.3.1. 問題

是否可以計算出每種水果的平均價格,即: 下面的方法是生成一個新的dataframe,是否有方法可以直接在原dataframe上直接出結果?

df['gross'] = df['price'] * df['weight']
df2 = df.groupby('item').agg({'gross':sum,'weight':sum})
df2['total_mean_price'] = round(df2['gross']/df2['weight'],2)
df2

3.5. 映射索引

修改索引、列名。

df4 = DataFrame({'color':['white','gray','purple','blue','green'], 'value':np.random.randint(10,size=5)})
new_index = {0:'first',1:'two',2:'three',3:'four',4:'five'}
new_col = {'color':'cc','value':'vv'}
df4.rename(index = new_index, columns = new_col)

4. 數據連接

pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, copy=True)

  • objs:Series,DataFrame或Panel對象的序列或映射。如果傳遞了dict,則排序的鍵將用作keys參數,除非它被傳遞,在這種情況下將選擇值(見下文)。任何None對象都將以靜默方式刪除,除非它們都是None,在這種情況下將引發ValueError。
  • axis :{0,1,...},默認為0.要連接的軸。
  • join:{'inner','outer'},默認為'outer'。如何處理其他軸上的索引。結合的外部和交叉的內部。
  • ignore_index:boolean,默認為False。如果為True,請不要在連接軸上使用索引值。生成的軸將標記為0,...,n - 1.如果要連接並置軸沒有有意義的索引信息的對象,這將非常有用。請注意,在連接中仍然遵循其他軸上的索引值。
  • join_axes:索引對象列表。用於其他n - 1軸的特定索引,而不是執行內部/外部設置邏輯。
  • keys:序列,默認無。使用傳遞的鍵作為最外層來構造層次索引。如果傳遞了多個級別,則應包含元組。
  • levels:序列列表,默認無。用於構造MultiIndex的特定級別(唯一值)。否則,他們將從鍵中推斷出來。
  • names:list,默認無。生成的分層索引中的級別的名稱。
  • verify_integrity:boolean,默認為False。檢查新的連鎖軸是否包含重復項。相對於實際數據連接,這可能非常昂貴。
  • copy:boolean,默認為True。如果為False,則不要不必要地復制數據。
# First, add the platform and device to the user usage - use a left join this time.
result = pd.merge(user_usage,
                 user_device[['use_id', 'platform', 'device']],
                 on='use_id',
                 how='left')
# At this point, the platform and device columns are included
# in the result along with all columns from user_usage
# Now, based on the "device" column in result, match the "Model" column in devices.
devices.rename(columns={"Retail Branding": "manufacturer"}, inplace=True)
result = pd.merge(result, 
                  devices[['manufacturer', 'Model']],
                  left_on='device',
                  right_on='Model',
                  how='left')

merge、join也可以用來合並,比較簡單。

5. 數據聚合

5.1. pandas內置計算函數

print(data['item'].count())
print(data['duration'].max())
print(data['duration'][data['item']=='call'].sum())
print(data['month'].value_counts())
print(data['network'].nunique())

另有uniquenunique等函數。

5.2. numpy中的函數

np.ptp(arr,axis=0)

如果不用ptp,下面的寫法就比較復雜了:

df_arr = pd.DataFrame(arr)
df_arr.loc[:,[0,1,2,3,4]].max() -df_arr.loc[:,[0,1,2,3,4]].min()

5.3. 聚合

data.groupby('month')['duration'].sum()

data[data['item']=='call'].groupby('network')['duration'].sum().sort_values(ascending=False)

data.groupby(['month','item'])['date'].count()

data.groupby('month',as_index=False).agg({'duration':['sum','count', 'max','min','mean']})

5.3.1. 輸出格式

data.groupby('month')['duration'].sum() # produces Pandas Series

data.groupby('month')[['duration']].sum() # Produces Pandas DataFrame
不同的聚合選項

5.3.2. 從 groupby 操作重命名分組統計信息

聚合字典語法非常靈活,可以在操作之前定義。還可以使用 lambda 函數內聯定義函數,以提取內置選項未提供的統計信息。

from datetime import timedelta
aggregations = {
    'duration':'sum',
    'date': [lambda x: max(x).date(), lambda x: (max(x) - timedelta(days=1)).date()]
}
grp = data.groupby('month',as_index=False).agg(aggregations)
grp.columns = grp.columns.droplevel(level=0)
grp.rename(columns={'sum':'duration_sum', r'<lambda_0>':'date', r'<lambda_1>':'date-1'})

6. 數據透視

參考文章

知識點 篩選行不僅可以用loc,還可以用query:

df.query('Product==["CPU","Software"]')

6.1. 設置數據類型為類別

設置數據類型為類別的好處:比如查詢單元格中是否有某個字符串,如果是str(object)類型,則需要對每一個單元格進行運算;如果是category類型,則不需要每個單元格運算,只需要對僅有的幾個類型進行運算即可。對於較大數據,會明顯提升速度。

df["Status"] = df["Status"].astype("category")
# 設置排序的順序.如果不設置,可能按字母順序。
df['Status'].cat.set_categories(["won","pending","presented","declined"],inplace=True)

6.2. 一般用法

table = pd.pivot_table(df,index=["Manager","Status"],columns=["Product"],values=["Quantity","Price"],
               aggfunc={"Quantity":len,"Price":[np.sum,np.mean]},fill_value=0)

6.3. 設置雙index

pd.pivot_table(df,index=["Name","Account"])

pivot_table 的一個令人困惑的問題是使用列和值。請記住,

6.4. 有無columns參數的區別

pd.pivot_table(df,index=['Manager','Rep'],values=['Price'],aggfunc=['sum'],fill_value=0)

pd.pivot_table(df,index=['Manager','Rep'],values=['Price'],columns=['Product'],aggfunc=[np.sum],fill_value=0)

6.5. 將項目移動到索引獲得不同的可視化效果:

pd.pivot_table(df,index=['Manager','Rep','Product'],values=['Price','Quantity'],aggfunc=[np.sum],fill_value=0)

6.6. margins=True可以實現看總數的需求。

pd.pivot_table(df,index=['Manager','Rep','Product'],values=['Price','Quantity'],aggfunc=[np.sum,np.mean],fill_value=0,margins=True)

6.7. set_categories的作用

Status就根據之前定義的順序排列

pd.pivot_table(df,index=['Manager','Status'],values=['Price'],aggfunc=[np.sum],fill_value=0,margins=True)

6.8. unstack()和stack()可以讓groupby(部分?)實現pivot_table的功能

## 以下兩句代碼效果一樣
pd.pivot_table(contb,index=['contbr_occupation'],columns=['party'],aggfunc='sum',values=['contb_receipt_amt'])

contb.groupby(['contbr_occupation','party'])['contb_receipt_amt'].sum().unstack()

6.9. 一張圖總結

pivot_table_datasheet

7. 讀取文件

讀取文件比較簡單,但是讀取csv文件的有個小技巧:有些csv文件的分隔符為一個或多個空格、一個或多個制表符,此時sep參數要設置為sep='\s+'

columns = ['user_id','order_dt', 'order_products', 'order_amount']
df = pd.read_csv('CDNOW_master.txt', names=columns, sep='\s+')

8. 寫入文件

  • pd.to_excel()對於dataframe數據的寫入很方便,缺點是如果工作簿已經存在則會重置工作簿,即原工作簿的內容都會擦掉,而且不能(?)調格式。
    with pd.ExcelWriter(xlsname) as writer:
        df1.to_excel(writer, sheet_name='XXX',index=False)
        df2.to_excel(writer, sheet_name='YYY',index=False)
  • openpyxl。
    • 把dataframe數據用openpyxl寫入excel優點是可以定向寫入,不影響原內容(不設定其他參數的情況下,也不修改原單元格的格式,如字體字號加粗等),適合在已設定好格式的模板上指定位置填充數據。
    import openpyxl as op
    ontent_1 = '上海' + str(int(month)) + '月' + str(int(day)) + '日日報未直報機構匯總數(' + str(not_direct_report) + '家未直報,另有8280北德意志銀行日報無數據)'
    file = 'filename'
    # 加載工作簿
    wb = op.load_workbook(file)
    # 選定工作表
    sh=wb["AAA"]
    # 對單個單元格填充內容,cell的三個參數分別是行號(1開始)、列號(1開始)、內容
    sh.cell(1,1,content_1)
  • 缺點是對於dataframe數據的操作不友好,需要用循環,暫時還沒學到別的高效的方法。
    sh=wb["BBB"]
    ## 表頭
    headlines = {1:'aa', 2:'bb', 3:'cc', 4:'dd', 5:str(int(month)) + '月' + str(int(day)) + '日余額', 6:'ee'}
    for col,headline in headlines.items():
        sh.cell(1,col,headline)
    sh.row_dimensions[1].height = 43.2
    ## 數據內容
    for col in mx_not_direct_repo.columns:
        a = mx_not_direct_repo[col].tolist()
        for i in range(len(a)):
            sh.cell(i+2,j,a[i])
        j += 1

9. 數據清洗

9.1. 刪除空值所在的行

  • isna只能判斷某個元素是否為NaN
df.isna()
  • anyall 方法
df.drop(df.loc[df.isna().any(axis=1)].index,inplace=True,axis=0)
df.reset_index()

any 方法的 axis 參數為 1 ,表名對每一行的多列來說,最終形成一個字段 TrueFalse ,效果就是列減少。參見 [[#axis 的理解]] 。

  • 直接使用pandas封裝好的 dropna
df.dropna(inplace=True)

9.2. 空值填充

9.2.1. 近鄰值進行填充

  • ffill 向前填充
  • bfill 向後填充
df.fillna(method='ffill',axis=0)

9.3. 刪除重復行

df.loc[1] = [1,1,1,1,1,1]
df.loc[3] = [1,1,1,1,1,1]
df.loc[5] = [1,1,1,1,1,1]
df.loc[7] = [1,1,1,1,1,1]
df.drop_duplicates(keep='first',inplace=True)

9.4. 刪除異常值所在的行

df = pd.DataFrame(np.random.random(size=(1000,3)),columns=['A','B','C'])
## 剔除大於2倍標准差的
df.drop(df.loc[~(df['C'] > (2 *df['C'].std()))].index,inplace=True,axis=0)

9.5. 替換

import pandas as pd
import numpy as np
from pandas import DataFrame,Series
df = DataFrame(np.random.randint(0,100,size=(8,7)))
## df.replace(to_replace=0, value='zero')
df.replace(to_replace={0:'zero',4:'four'})

9.5.1. 指定列替換

## 替換第4列的0
df.replace(to_replace={4:0},value=666)
df.columns = ['zero','one','two','three','four','five','six']
# 下面兩種方式效果一樣
df.replace(to_replace={'four':0},value=777)
# df.replace(to_replace={'four':{0:777}})

可否對指定行替換?

df.loc[3][df.loc[3] == 18] = 200
df
"""
是否還有別的方法?
"""

9.5.2. map替換

mapSeris的一個方法。 map字典可以進行映射操作。

dic_data = {
    'name':['張三','李四','王老五'],
    'salary':[22222,7777,11111]
}
df = DataFrame(dic_data)
dic_map = {
    '張三':'tom',
    '李四':'jay',
    '王老五':'jerry'
}
df['e_name'] = df['name'].map(dic_map)
df

9.5.3. 幾種替換方法比較:mapreplacenp.select

  • map : 將列裡面的所有的數據進行替換;如果不存在相關鍵值,則賦值NaN
  • replace : 替換其中一部分
  • np.select : 可以替換,需設定好default值。

map 也可以用別的方式來達到替換某些索引行的目的,即傳入函數,而不是字典。這種方法可以替換 np.select

dic_map = {
    '張三':'tom',
    '李四':'jay',
}
# dict.get(a,b),如果dict中存在鍵a,則返回其對應的值,否則返回b。
f = lambda x : dic_map.get(x,x)
df['name'] = df['name'].map(f)
df

替換行列名,可以用rename。參考[[#映射索引]]節。

map函數可以做運算工具:

# 超過3000的部分繳納50%的稅,計算稅後工資
df['net_pay'] = df['salary'].map(lambda x: (x - 3000) * 0.5 + 3000)
df

運算工具主要有mapapplyapplymap ,用法參考[[#map 、 apply 、 applymap 用法]]。

9.6. 隨機抽樣

9.6.1. 排序實現隨機抽樣:將數據打亂之後用切片

  • take
  • permutation
"""
take的第一個參數只能用隱式索引,而不能用顯式索引,因為這個列表一般是要自動生成的,而不是讓用戶自己寫列名等操作。
"""
df = DataFrame(data=np.random.randint(0,100,size=(100,3)),columns=['A','B','C'])
## take的用法
df.take([2,0,1,4],axis=0)

## take更一般的用法:自動生成,將行和列均打散
df.take(np.random.permutation(3),axis=1).take(np.random.permutation(100),axis=0)[:10]

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved