新列和行迭代



我正在尝试在现有数据集中添加一个新列(pandas dataframe)。此新列包含满足特定条件的元素(请参阅下面的代码)。我正在迭代行,但我无法根据条件更改行的值(行应具有值row_value[0] = var2row_value[0] = varB)。

for index, row in sample_dataset.iterrows():
row_value = ['Missing']
for var1, var2 in var3:
if row[0].endswith(var1):
row_value[0] = var2
break
for varA,varB in varC:
if row[0].endswith(varA): 
row_value[0] = varB
break

任何帮助将不胜感激。谢谢

例:

原始数据集:

Column
hello_world.a
goodmorning_world.b
bye_world.1
...

列表是:

var1=['1','2','3']
var2=['11','22','33']
var3=list(zip(var1, var2))

同样适用于varA, varB, varC

varA=['a','b','c']
varB=['aa','bb','cc']
varC=list(zip(varA, varB))

我想要这样的东西:

预期产出

Column                  New_column
hello_world.a               aa
goodmorning_world.b         bb
bye_world.1                 11
...

那么,让我们一步一步地学习你的代码,首先让我们定义数据帧

import pandas as pd
# create dataframe with nans in the new column you want to fill
sample_dataset = pd.DataFrame({'Column':['hello_world.a','goodmorning_world.b','bye_world.1']})
# create new column which we will fill later 
sample_dataset['New_column'] = pd.Series(index = sample_dataset.index, dtype='object')

请注意,指定新列的类型很重要,因为您要实现的是创建一个包含混合元素类型、数字和字符串的新列,并且只有 python 'objects' 可以容纳混合类型。

让我们打印它看看它的外观

print(sample_dataset)
Out:
Column  New_column
0        hello_world.a         NaN
1  goodmorning_world.b         NaN
2          bye_world.1         NaN    

现在让我们转到代码的其余部分:

# the other variables you defined 
var1=['1','2','3']
var2=['11','22','33']
var3=list(zip(var1, var2))
varA=['a','b','c']
varB=['aa','bb','cc']
varC=list(zip(varA, varB))
# your code
for index, row in sample_dataset.iterrows():
row_value = ['Missing']
for var1, var2 in var3:
if row[0]. endswith(var1):
row_value[0] = var2
break
for varA,varB in varC:
if row[0].endswith(varA): 
row_value[0] = varB
break

让我们检查一下您的代码是否对数据帧做了什么

Out:
Column  New_column
0        hello_world.a         NaN
1  goodmorning_world.b         NaN
2          bye_world.1         NaN

似乎什么都没有改变,但确实发生了一些事情,这是row_value。如果我在运行您的代码后尝试打印它,我会得到:

print(row_value)
Out:
['11']

同样,这是最引人注目的错误,因为它表明您的问题不仅在于熊猫和数据帧,还在于一般的编程。如果要修改变量,则必须访问该变量,此处要更改的变量是数据帧,称为sample_dataset,但不是调用它,而是在以下行中调用row_value:

row_value[0] = var2
row_value[0] = varB

这就是为什么在代码末尾row_value不再是['Missing']而是['11'],所以你正在改变一些东西,而不是你的数据帧。

那么如何更新初始数据帧的新列中的值呢?以下是您应该如何操作:

# iterating through rows, this is correct
for index, row in sample_dataset.iterrows():

# you don't need to define row_value, but you want to access the value of 'Column' in the current row
value = row['Column']

# you could just do "for var1, var2 in list(zip(var1, var2))" without defining var3, not a mistake but it makes the code more concise
for var1, var2 in var3:

# using .endswith() will raise an error when you try to apply it to numbers, an alternative that works for both numbers and string is to simply access the last element of the array with [-1]
if value[-1] == var1:

# this is how you change an element in a dataframe, i.e. using .at[index, column]
# here we say that we want to change the element in the current index in the column 'New_colum' with var2 
sample_dataset.at[index,'New_column'] = var2
break

for varA,varB in varC:

# same story as before
if value[-1] == varA: 

sample_dataset.at[index,'New_column'] = varB
break

让我们再次打印数据帧以检查这是否有效:

print(sample_dataset)
Out:
Column New_column
0        hello_world.a         aa
1  goodmorning_world.b         bb
2          bye_world.1         11

因此,这次我们确实访问了数据帧并成功更改了New_column的值。浏览代码,如果您有疑问,请发表评论,我可以更详细地解释它。

最后要注意的是,如果您只想将第一行中的最后一个字符放在新列中加倍,那么有更好的方法可以做到这一点。例如:

for index, row in sample_dataset.iterrows():

value = row['Column']

sample_dataset.at[index, 'New_column'] = value[-1]*2 

同样,如果我们打印它,我们可以看到三行代码足以完成这项工作:

print(sample_dataset)
Out:
Column New_column
0        hello_world.a         aa
1  goodmorning_world.b         bb
2          bye_world.1         11

这样,您就不需要定义varA,B,C和所有其他内容,也不需要制动器或嵌套循环。我们甚至可以使用 .apply() 将代码压缩为一行

sample_dataset['New_column'] = sample_dataset.apply(lambda x: x['Column'][-1]*2, axis=1)

这将再次为您提供与以前相同的结果,但是如果您的代码遇到问题,这可能是您希望留给将来会更有信心的东西。

另请注意,最后两个方法将创建所有字符串元素,因此即使是最后一个元素 11 也将是字符串而不是 float64。这可能是您想要避免的事情,在这种情况下,您应该只使用您的代码,但一般来说,在列中混合类型并不是一件好事。

编辑

如果要提取符合特定规则的字符串的一部分(在本例中为最后一个句点之后的所有内容),则需要使用正则表达式(或正则表达式)。python中的正则表达式是在库中实现的,你需要做的是:

# import library
import re
# define a patter of interest, this specific pattern means 'everything from the end of the string until you find a period'
pattern = r"([^.]*$)"
# now you can extract the final part from each element in your dataframe using re.search
last_part = re.search(pattern, element).groups()[0]

为了展示它的作用,让我们取一个像 'hello_world.com' 这样的假值并对其应用正则表达式:

print(re.search(pattern, 'hello_world.com').groups()[0])
Out:
com

现在,您想使用 re.search 更改代码值 [-1] 所以

if value[-1] == var1:
if value[-1] == varB:

应该成为

if re.search(pattern, value).groups()[0] == var1:
if re.search(pattern, value).groups()[0] == varB:

请记住为 re 添加导入,并在代码开头定义模式。

最新更新