【问题标题】:Data wrangling in Python, calculate value from some conditionsPython中的数据争吵,根据某些条件计算值
【发布时间】:2021-12-28 02:23:42
【问题描述】:

我在下面的 Python 中有一个数据框:

import pandas as pd
df = pd.DataFrame({
    'CRDACCT_DLQ_CYC_1_MNTH_AGO' : [3, 2, 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C'], 
    'CRDACCT_DLQ_CYC_2_MNTH_AGO': [4, 3, 3, 3, 3, 3, 2, 0, 5, 4, 3, 2, 0, 2, 2, 2, 2, 2, 2, 0, 2, 2, 0, 2], 
    'CRDACCT_DLQ_CYC_3_MNTH_AGO': [8, 7, 6, 5, 4, 3, 2, 'F', 'F', 0, 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'F', 'C', 'C', 'F', 'F'], 
    'CRDACCT_DLQ_CYC_4_MNTH_AGO' : [0, 2, 'F', 'F', 'C', 'C', 'C', 'C', 0, 2, 0, 2, 0, 2, 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'F', 'C', 'F'], 
    'CRDACCT_DLQ_CYC_5_MNTH_AGO' : [2, 2, 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C'], 
    'CRDACCT_DLQ_CYC_6_MNTH_AGO' : [2, 2, 2, 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 0, 2, 0, 2, 0], 
    'CRDACCT_DLQ_CYC_7_MNTH_AGO' : [3, 3, 2, 'C', 'C', 'C', 'F', 0, 6, 5, 4, 3, 2, 2, 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C'], 
    'CRDACCT_DLQ_CYC_8_MNTH_AGO' : [5, 4, 4, 3, 3, 2, 3, 2, 2, 2, 1, 2, 0, 2, 'C', 'C', 0, 2, 2, 2, 'C', 'C', 0, 'Z'], 
    'CRDACCT_DLQ_CYC_9_MNTH_AGO' : [2, 2, 'C', 0, 2, 0, 2, 'C', 'C', 'C', 'C', 'C', 0, 3, 2, 'C', 'F', 'C', 'F', 'F', 'F', 'F', 'F', 'F'], 
    'CRDACCT_DLQ_CYC_10_MNTH_AGO' : [5, 4, 3, 2, 3, 2, 0, 2, 0, 2, 'C', 'C', 'F', 2, 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'C'], 
    'CRDACCT_DLQ_CYC_11_MNTH_AGO' : [4, 3, 2, 'F', 2, 0, 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z'], 
    'CRDACCT_DLQ_CYC_12_MNTH_AGO' : ['F', 8, 7, 6, 5, 4, 3, 2, 'C', 'C', 'C', 0, 2, 'C', 'C', 0, 2, 0, 3, 2, 'C', 'C', 'F', 2]
})

df.head()

我想将这些值(字符串值:C、F 和 Z)转换为具有以下条件的某些类别:如果 CRDACCT_DLQ_CYC_1_MNTH_AGO、CRDACCT_DLQ_CYC_2_MNTH_AGO、.......、CRDACCT_DLQ_CYC_12_MNTH_AGO 列中的值组成:

C = 0
F = 0
Z = 0
else value  = value 

#Convert value
df = df.replace({'C': 0, 'F': 0, 'Z': 0,' ':0}).astype(int)

然后,我想创建一个名为 MSD 的新列。 MSD 代表自拖欠以来的月份。 MSD 是通过识别 CRDACCT_DLQ_CYC_1_MNTH_AGO、CRDACCT_DLQ_CYC_2_MNTH_AGO、......直到 CRDACCT_DLQ_CYC_12_MNTH_AGO 的 12 列中的每一列来计算的:

If value in CRDACCT_DLQ_CYC_1_MNTH_AGO > 1 then MSD = 1, otherwise MSD=0 or
If value in CRDACCT_DLQ_CYC_2_MNTH_AGO > 1 then MSD = 2, otherwise MSD=0 or
If value in CRDACCT_DLQ_CYC_3_MNTH_AGO > 1 then MSD = 3, otherwise MSD=0 or
If value in CRDACCT_DLQ_CYC_4_MNTH_AGO > 1 then MSD = 4, otherwise MSD=0 or
If value in CRDACCT_DLQ_CYC_5_MNTH_AGO > 1 then MSD = 5, otherwise MSD=0 or
If value in CRDACCT_DLQ_CYC_6_MNTH_AGO > 1 then MSD = 6, otherwise MSD=0 or
If value in CRDACCT_DLQ_CYC_7_MNTH_AGO > 1 then MSD = 7, otherwise MSD=0 or
If value in CRDACCT_DLQ_CYC_8_MNTH_AGO > 1 then MSD = 8, otherwise MSD=0 or
If value in CRDACCT_DLQ_CYC_9_MNTH_AGO > 1 then MSD = 9, otherwise MSD=0 or
If value in CRDACCT_DLQ_CYC_10_MNTH_AGO > 1 then MSD = 10, otherwise MSD=0 or
If value in CRDACCT_DLQ_CYC_11_MNTH_AGO > 1 then MSD = 11, otherwise MSD=0 or
If value in CRDACCT_DLQ_CYC_12_MNTH_AGO > 1 then MSD = 12, otherwise MSD=0
Note: otherwise if value 1 and 0, then MSD = 0.

例如:

  • 索引 0,MSD =1,因为值 3 > 1 在 CRDACCT_DLQ_CYC_1_MNTH_AGO 中 (我们不需要检查 CRDACCT_DLQ_CYC_2_MNTH_AGO > 1 因为我们有 自 CRDACCT_DLQ_CYC_1_MNTH_AGO) 拖欠以来发现的月份,因此 MSD 在 1 MNTH 前

  • 索引 1,MSD=1

  • 索引 2,MSD=2

  • 索引 3,MSD=2,因为值 3 > 1 在 CRDACCT_DLQ_CYC_2_MNTH_AGO,因此 MSD 在 2 MNTH AGO

  • 索引 4,MSD=2

注意:通过在这些条件下检查每 12 列,如果每列 CRDACCT_DLQ_CYC_1_MNTH_AGO、.....和 ​​CRDACCT_DLQ_CYC_12_MNTH_AGO 中的所有值 = 0,则 MSD 应 = 0。

一般是检查每12列的值>1,然后根据列名确定MSD值CRDACCT_DLQ_CYC_x_MNTH_AGOx就是MSD的值如果 > 1.

【问题讨论】:

  • 您提出的代码有什么问题?我们不是来为你编写整个程序的——如果你被困在某个地方,你可以提出一个特定的问题或发布一个你试图调试的错误。否则,这个问题很可能因缺乏焦点而被关闭。见how to ask a question

标签: python pandas conditional-statements data-wrangling


【解决方案1】:

我试图了解您遇到了什么问题,根据我的理解,您似乎想要实现两个结果:

  1. 您想替换数据帧中的值:"C""F""Z",只要它们存在整数值 0,否则不理会该值,这可以通过以下方式完成:
df.replace(to_replace=["C", "F", "Z"], value=0, inplace=True)
# setting the parameter 'inplace' to the value True to apply the transformation to the requested DataFrame: 'df'
  1. 在此之后,您希望有一个整数类型的新列,标记为 "MSD",并且对于它应该包含的值,您希望它如下所示:
    对于DataFrame中的每一行,按顺序查找每一列下的值,如果遇到任何大于1的值,停止查找其余列的值,对于遇到这种情况的列,提取列标签中的数值并将其分配给同一行中的列"MSD"。这可以按如下方式完成:
def numberInColumnLabel(columnLabel):
    """
    function that extracts numerical value from given string in the format: CRDACCT_DLQ_CYC_[x]_MNTH_AGO , where [x] is the numerical value, and returns it.
    """
    phraseBeforeNumber = "CYC_"
    phraseAfterNumber = "_MNTH"
    
    numberStartingIndex = columnLabel.find(phraseBeforeNumber) + len(phraseBeforeNumber)
    numberEndingIndex = columnLabel.find(phraseAfterNumber)
    
    number = int( columnLabel[numberStartingIndex:numberEndingIndex] )
    return number

df["MSD"] = 0   # initialize column 'MSD' with a default value of 0

for rowIndex in range(0, df.shape[0]): #iterate through each row's index
    for columnLabel in df.columns: #iterate through each column label for that row
        if(int(df[columnLabel][rowIndex]) > 1):
            df.loc[rowIndex, "MSD"] = numberInColumnLabel(columnLabel)
            break

【讨论】:

    【解决方案2】:

    它不是很漂亮,但这种单线应该可以解决问题;)

    df['MSD'] = (df > 1).astype(int).apply(lambda row: int(row.idxmax().split('_')[3]) if row.sum() >=1 else 0, axis=1)
    

    基本上 - 检查哪些值大于 1,获取高于 1 的每一行的第一列(您定义的 MSD),并且不要忘记在它为 0 时检查边缘情况。

    【讨论】:

    • 我已经检查过了,结果和我预期的一样。一切都是正确的。谢谢,感谢您为创建新列而使用此技巧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-25
    • 2016-10-12
    相关资源
    最近更新 更多