繁体   English   中英

根据条件使用嵌套循环替换 pandas dataframe 中的值

[英]Replacing values in pandas dataframe using nested loop based on conditions

如果当前行值 df.iloc[i,0] 通过迭代 dataframe df 为 0,我想用 1 替换前 3 个值。 替换值后,dafaframe 迭代应跳过新添加的值从下一个索引开始- 在以下示例中从索引 7 开始。如果 dataframe 中的最后两个值是 1,则这也应替换为 0-替换两个值仅当这些值是最后一个值时才会发生。 在示例中,索引为 9 和 10 的值就是这种情况。

原装 DataFrame:

  index       column 1 
    0            1        
    1            1      
    2            1        
    3            0        
    4            1        
    5            1        
    6            1        
    7            1
    8            0
    9            1
   10            1

我想要的新 DataFrame 应该如下所示:

 index       column 1 
    0            1        
    1            1      
    2            1        
    3            0        
    4          **0** --> new value 
    5          **0** --> new value 
    6          **0** --> new value        
    7            1    
    8            0
    9          **0** --> new value 
   10          **0** --> new value 

我键入该代码,但它不起作用。

for i in range(len(df)):

   print(df.iloc[i,0])

if df.iloc[i,0]== 0 :

    j= i + 1 
    
    while j <= i + 3:
        
        df.iloc[j,1]= 0
        
        j= j+ 1 
    
i = i + 4 #this is used to skip the new values and starting by the next firt index 


if (len(df)- i < 2) and (df.iloc[i,0]== 0): #replacing the two last values by 0 if the previous value is 0. 
    
    j= i + 1 
        
        while j <= len(df)
            
            df.iloc[j,1]= 0

您可以在代码中改进和更改许多问题。

首先,使用for i in range(len(df)):循环通常不是一个好主意。 它不是 Pandas。 Pandas 有**df.size** (用于代替len(df) 。你在 Python 中循环,如:

for i, colmn_value in enumerate(df[colmn_name]): 

如果您确实需要索引(在大多数情况下,包括您的问题中不需要的索引)或使用

for colmn_value in df[colmn_name]: 

我在底部提供了您现在可以使用的更正代码。 我为使您的代码运行而修复的问题在代码中进行了说明,因此请查看它们。 这些问题只是初学者在学习如何编码时遇到的常见“陷阱”。 主要想法是正确的。

您似乎已经有使用另一种编程语言(例如 C 或 C++)的编程经验,但是...不要指望for i in range(N): Python 循环在每次迭代时增加索引值循环以表现得像 aloop ,因此您可以在循环中更改它以跳过索引。 您不能在 Python for 循环中从 range()、enumerate() 或其他可迭代对象中获取其值。 如果要更改循环内的索引,请使用 Python 'while' 循环。

我在下面为同一任务提供的代码使用“技巧” ,如果在列中检测到零值,则将替换从 3 倒计时到 0,并且仅if countdown:替换值。

VERBOSE更改为False以关闭显示代码如何在后台工作的打印行。 由于它是 Python,因此代码本身主要解释了在 Python 中使用的可用适当语法,听起来像是在谈论要做什么。

VERBOSE = True
if VERBOSE: new_colmn_value = "**0**"
else:       new_colmn_value =    0
new_colmn = []
countdown = 0
for df_colmn_val in df.iloc[:,0]: # i.e. "column 1"
    new_colmn.append(new_colmn_value if countdown else df_colmn_val)
    if VERBOSE: 
        print(f'{df_colmn_val=}, {countdown=}, new_colmn={new_colmn_value if countdown else df_colmn_val}')
    if df_colmn_val == 0 and not countdown:
       countdown = 4
    if countdown: countdown -= 1 
df.iloc[:,[0]] = new_colmn # same as df['column 1'] = new_colmn
print(df)

给出:

df_colmn_val=1, countdown=0, new_colmn=1
df_colmn_val=1, countdown=0, new_colmn=1
df_colmn_val=1, countdown=0, new_colmn=1
df_colmn_val=0, countdown=0, new_colmn=0
df_colmn_val=1, countdown=3, new_colmn=**0**
df_colmn_val=1, countdown=2, new_colmn=**0**
df_colmn_val=1, countdown=1, new_colmn=**0**
df_colmn_val=1, countdown=0, new_colmn=1
df_colmn_val=0, countdown=0, new_colmn=0
df_colmn_val=1, countdown=3, new_colmn=**0**
df_colmn_val=1, countdown=2, new_colmn=**0**
      column 1
index         
0            1
1            1
2            1
3            0
4        **0**
5        **0**
6        **0**
7            1
8            0
9        **0**
10       **0**

在我已修复的您自己的代码下方,以便它现在运行并执行它的编写目的:

for i in range(len(df)):
   print(df.iloc[i,0])
   if df.iloc[i,0]== 0 :
       j= i + 1 
       while ( j <= i + 3 ) and j < df.size: # handles table end !!!
           print(f'{i=} {j=}')
           df.iloc[j, 0] = '**0**' # first column has index 0 !!!
           j= j+ 1 
       # i = i + 4 # this is used to skip the new values and starting by the next firt index
       # !!!### changing i in the loop will NOT do what you expect it to do !!!
       # the next i will be just i+1 getting its value from range() and NOT i+4              
   this_is_not_necessary_as_it_is_handled_already_above = """
   if (len(df)- i < 2) and (df.iloc[i,0]== 0): #replacing the two last values by 0 if the previous value is 0. 
       j= i + 1 
       while j <= len(df):
           df.iloc[j,1]= 0
   """

印刷:

1
1
1
0
i=3 j=4
i=3 j=5
i=3 j=6
**0**
**0**
**0**
1
0
i=8 j=9
i=8 j=10
**0**
**0**
      column 1
index         
0            1
1            1
2            1
3            0
4        **0**
5        **0**
6        **0**
7            1
8            0
9        **0**
10       **0**

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM