[英]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.