簡體   English   中英

Pandas 根據每列的條件獲取最后一個值的位置(高效)

[英]Pandas get postion of last value based on condition for each column (efficiently)

我想獲取我的 dataframe 的每一列中值1最后出現在哪一行的信息。鑒於最后一行索引,我想計算出現的“新近度”。 像這樣:

>> df = pandas.DataFrame({"a":[0,0,1,0,0]," b":[1,1,1,1,1],"c":[1,0,0,0,1],"d":[0,0,0,0,0]})
>> df
   a  b  c  d
0  0  1  1  0
1  0  1  0  0
2  1  1  0  0
3  0  1  0  0
4  0  1  1  0

期望的結果:

>> calculate_recency_vector(df)
[3,1,1,None]

期望的結果顯示每列“多少行之前”最后一次出現值1 例如,對於列a ,值1最后出現在倒數第三行,因此結果向量中的新近度為3 任何想法如何實現這個?

編輯:為避免混淆,我將最后一列所需的 output 從0更改為None 此列沒有新近度,因為根本沒有出現值1

編輯二:感謝您的精彩回答。 我必須在形狀為 (42.250) 的數據幀上計算這個近因向量大約 150k 次。 更有效的解決方案將不勝感激。

更快更清潔的無環路解決方案:

>> def calculate_recency_for_one_column(column: pd.Series) -> int:
>>     non_zero_values_of_col = column[column.astype(bool)]
>>     if non_zero_values_of_col.empty:
>>         return 0
>>     return len(column) - non_zero_values_of_col.index[-1]

>> df = pd.DataFrame({"a":[0,0,1,0,0],"b":[1,1,1,1,1],"c":[1,0,0,0,1],"d":[0,0,0,0,0]})

>> df.apply(lambda column: calculate_recency_for_one_column(column),axis=0)

a    3
b    1
c    1
d    0
dtype: int64

旁注:使用pd.apply()很慢(如此解釋)。 存在更快的解決方案,例如使用np.where或使用apply(...,raw=True) 有關詳細信息,請參閱此問題

使用此示例 dataframe,您可以定義一個 function,如下所示:

def calculate_recency_vector(df: pd.DataFrame, condition: int) -> list:
    recency_vector = []

    for col in df.columns:
        last = 0
        for i, y in enumerate(df[col].to_list()):
            if y == condition:
                last = i

        recency = len(df[col].to_list()) - last
        if recency == len(df[col].to_list()):
            recency = None

        recency_vector.append(recency)

    return recency_vector

運行 function,它將返回:

calculate_recency_vector(df, 1)
[3, 1, 1, None]

實現此 function 的一種直接方法是使用循環遍歷 DataFrame 中的每一列,並在該循環內使用另一個循環遍歷列中的每一行。 對於每一行,檢查值是否為 1。如果是,則更新變量以存儲 len(df[column])-index。 內部循環完成后,返回存儲的值作為該列的新近度。 如果 1 從未出現在列中,則返回 None。

import pandas
def calculate_recency_vector(df):
    recency_vector = []
    for column in df:
        last_occurrence = None
        for index, value in df[column].iteritems():
            if value == 1:
                last_occurrence =len(df[column])-index
        recency_vector.append(last_occurrence)
    return recency_vector


df = pandas.DataFrame({"a":[0,0,1,0,0]," b":[1,1,1,1,1],"c":[1,0,0,0,1],"d":[0,0,0,0,0]})
print(calculate_recency_vector(df))

這個

df = pandas.DataFrame({"a":[0,0,1,0,0]," b":[1,1,1,1,1],"c":[1,0,0,0,1],"d":[0,0,0,0,0]})
df.apply(lambda x : ([df.shape[0] - i for i ,v in x.items() if v==1] or [None])[-1], axis=0)

產生所需的 output 作為pd.Series ,唯一的區別是結果是 float 而None被 pandas Nan取代,然后你可以采用所需的列

暫無
暫無

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

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