Итак, давайте go шаг за шагом пройдем ваш код, сначала давайте определим фрейм данных
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 «объекты» могут содержать смешанные типы.
Давайте распечатаем его, чтобы увидеть, как оно выглядит
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']
Опять же, это самая поразительная ошибка, поскольку она показывает, что ваша проблема не только с pandas и фреймами данных, но и с программированием в целом , Если вы хотите изменить переменную, вам нужно получить доступ к этой переменной, здесь переменная, которую вы хотите изменить, это ваш фрейм данных, который называется sample_dataset, но вместо того, чтобы вызывать его, вы вызываете row_value в следующих строках:
row_value[0] = var2
row_value[0] = varB
Именно поэтому в конце вашего кода row_value больше не [[отсутствует]], а ['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 успешно. Go хотя код и, если у вас есть сомнения, просто прокомментируйте, я могу объяснить это более подробно.
В качестве последнего замечания, если вам нужно просто взять последний символ в первой строке и дважды это в новой колонке, есть гораздо лучшие способы сделать это. Например:
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. Это может быть то, чего вы хотите избежать, и в этом случае вы должны просто использовать свой код, но в целом смешивать типы в столбце не очень хорошо.
Редактировать
, если вы хотите извлечь часть строки, соответствующую указанному правилу c (в данном случае, все после последнего периода), вам нужно использовать регулярные выражения (или регулярное выражение ). Regex в python реализован в библиотеке re, что вам нужно сделать:
# 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
Теперь вы хотите изменить значение кода [-1] с помощью re.search, поэтому
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 и определить шаблон в начале вашего кода.