簡體   English   中英

Python Pandas Dataframe - 行級操作

[英]Python Pandas Dataframe - row level operations

我需要對一張數據表進行大量的行級操作(幾頁代碼)。

例如if row.Col_A == 'X': row.Col_B = 'Y'

我相信 iterrows 不適合更改表值。 因此,我已將表格轉換為 DotMap 字典列表。 有了這個,我可以遍歷列表並為每個字典(行)編寫上面的代碼並保存更改。

是否可以將數據作為 DataFrame 執行此操作?

有很多邏輯,我認為這樣寫最清楚,所以我不想使用 map 或應用函數。

讓我們有以下示例 dataframe:

import pandas as pd
import numpy as np

some_data = pd.DataFrame({
    'col_a': [1, 2, 1, 2, 3, 4, 3, 4],
    'col_b': ['a', 'b', 'c', 'c', 'a', 'b', 'z', 'z']
})

我們希望基於一個(或多個)現有列的值創建一個新列。

如果您只有兩個選項,我建議您使用 numpy.where 像這樣:

some_data['np_where_example'] = np.where(some_data.col_a < 3, 'less_than_3', 'greater_than_3')
print(some_data)
>>>
   col_a col_b           col_c map_example np_where_example  \
0      1     a     less_than_3         NaN      less_than_3   
1      2     b     less_than_3         BBB      less_than_3   
2      1     c     less_than_3         NaN      less_than_3   
3      2     c     less_than_3         NaN      less_than_3   
4      3     a  greater_than_3         NaN   greater_than_3   
5      4     b  greater_than_3         BBB   greater_than_3   
6      3     z  greater_than_3         ZZZ   greater_than_3   
7      4     z  greater_than_3         ZZZ   greater_than_3 

# multiple conditions
some_data['np_where_multiple_conditions'] = np.where(((some_data.col_a >= 3) & (some_data.col_b == 'z')),
                                                     'is_true',
                                                     'is_false')
print(some_data)
>>>
   col_a col_b np_where_multiple_conditions
0      1     a                     is_false
1      2     b                     is_false
2      1     c                     is_false
3      2     c                     is_false
4      3     a                     is_false
5      4     b                     is_false
6      3     z                      is_true
7      4     z                      is_true

如果您有很多選擇,那么 pandas.map 會更好:

some_data['map_example'] = some_data.col_b.map({
    'b': 'BBB',
    'z': 'ZZZ'
})
print(some_data)
>>>
   col_a col_b map_example
0      1     a         NaN
1      2     b         BBB
2      1     c         NaN
3      2     c         NaN
4      3     a         NaN
5      4     b         BBB
6      3     z         ZZZ
7      4     z         ZZZ

如您所見,在所有情況下,未指定條件的值的計算結果為NaN

您可以通過以下方式將應用 function 與 lambda 一起使用:

df['Col_B'] = df['Col_A'].apply(lambda a: 'Y' if a == 'X' else 'N')

這會在 dataframe df 上創建列 Col_B,方法是查看 Col_A 並在 Col_A 為“X”時給出值“Y”,否則為“N”。

如果您的 function 有點復雜,您可以預先定義它並在應用 function 中調用它,如下所示:

def yes_or_no(x):
    if x == 'X':
        return 'Y'
    else:
        return 'N'
df['Col_B'] = df['Col_A'].apply(lambda a: yes_or_no(a))

按行迭代 dataframe 並更改列值的一種可能方法是:

  1. 確保索引中沒有重復的值(如果有,只需使用reset_index獲取可接受的索引)

  2. 遍歷索引並使用at訪問各個值

     for ix in df.index: if df.at[ix, 'A'] ==...: df.at[ix, 'B'] = z

或者,如果您可以通過它們的位置而不是它們的名稱來訪問列,則可以使用更有效的iat

for i in range(len(df)):
    if df.iat[i, index_col_A] == ... :
        df.iat[i, index_col_B] = z

當您直接訪問單個元素時,您可以避免每行創建一個系列的iterrows開銷,並且可以執行更改。 AFAIK,當您不能使用矢量化 Pandas 或 numpy 方法時,這是一種不太糟糕的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM