Python 中的数据整理,根据某些条件计算值
Data wrangling in Python, calculate value from some conditions
我在下面的 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 是通过识别 12 列中的每一列 CRDACCT_DLQ_CYC_1_MNTH_AGO、CRDACCT_DLQ_CYC_2_MNTH_AGO、......直到 CRDACCT_DLQ_CYC_12_MNTH_AGO 具有这种条件的每一列来计算:
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.
例如:
index 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 AGO
索引 1,MSD=1,
索引 2,MSD=2,
index 3, MSD=2, 因为值 3 > 1 在
CRDACCT_DLQ_CYC_2_MNTH_AGO,因此 MSD 在 2 MNTH AGO
索引 4,MSD=2
注意: 通过使用这些条件检查每 12 列,如果每列中的所有值 = 0 CRDACCT_DLQ_CYC_1_MNTH_AGO,......并且 CRDACCT_DLQ_CYC_12_MNTH_AGO, 那么 MSD 应该是 = 0.
一般是检查每12列的值>1然后根据列名确定MSD值CRDACCT_DLQ_CYC_x_MNTH_AGO, x 将是 MSD 的值,如果 > 1.
它不是很漂亮,但这个单线应该可以解决问题;)
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 时不要忘记检查边缘情况。
我试图了解你的problem/s是什么,据我了解,你似乎想要达到两个结果:
- 您想用整数值
0
替换 DataFrame 中的值:"C"
、"F"
和 "Z"
,否则保留值,这可以通过以下方式完成:
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'
- 在此之后,您想要一个整数类型的新列,标记为
"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
我在下面的 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 是通过识别 12 列中的每一列 CRDACCT_DLQ_CYC_1_MNTH_AGO、CRDACCT_DLQ_CYC_2_MNTH_AGO、......直到 CRDACCT_DLQ_CYC_12_MNTH_AGO 具有这种条件的每一列来计算:
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.
例如:
index 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 AGO
索引 1,MSD=1,
索引 2,MSD=2,
index 3, MSD=2, 因为值 3 > 1 在 CRDACCT_DLQ_CYC_2_MNTH_AGO,因此 MSD 在 2 MNTH AGO
索引 4,MSD=2
注意: 通过使用这些条件检查每 12 列,如果每列中的所有值 = 0 CRDACCT_DLQ_CYC_1_MNTH_AGO,......并且 CRDACCT_DLQ_CYC_12_MNTH_AGO, 那么 MSD 应该是 = 0.
一般是检查每12列的值>1然后根据列名确定MSD值CRDACCT_DLQ_CYC_x_MNTH_AGO, x 将是 MSD 的值,如果 > 1.
它不是很漂亮,但这个单线应该可以解决问题;)
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 时不要忘记检查边缘情况。
我试图了解你的problem/s是什么,据我了解,你似乎想要达到两个结果:
- 您想用整数值
0
替换 DataFrame 中的值:"C"
、"F"
和"Z"
,否则保留值,这可以通过以下方式完成:
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'
- 在此之后,您想要一个整数类型的新列,标记为
"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