#python #pandas
#python #pandas
Вопрос:
Я пытаюсь создать новый столбец на основе моего первого столбца. Например,
I have a list of a = ["A", "B", "C"] and existing dataframe
Race Boy Girl
W 0 1
B 1 0
H 1 1
W 1 0
B 0 0
H 0 1
W 1 0
B 1 1
H 0 1
Моя цель — создать новый столбец и добавить к нему значение на основе интервалов W, B, H. Чтобы конечный результат выглядел как:
Race Boy Girl New Column
W 0 1 A
B 1 0 A
H 1 1 A
W 1 0 B
B 0 0 B
H 0 1 B
W 1 0 C
B 1 1 C
H 0 1 C
Интервал W, B, H согласован, и я хочу добавлять новое значение в новый столбец каждый раз, когда я вижу W. Данные длиннее этого.
Я перепробовал все возможные способы, но не смог придумать код. Я буду рад, если кто-нибудь сможет помочь, а также объяснить процесс. Спасибо
Комментарии:
1. Сколько
W
существует и сколько из этих новых значенийA
,B
C
у вас есть в наличии?2. Извините, есть 67 Ws и 67 A B C
3. Количество Ws в dataframe совпадает с количеством значений, которые у меня есть в списке для нового столбца
Ответ №1:
Вот что вы можете сделать:
Используйте цикл для создания списка, повторяющегося для столбца.
for i in len(dataframe['Race']):
#Create list for last column
Как только у вас будет этот список, вы можете добавить его в список с помощью:
dataframe['New Column'] = list
Комментарии:
1. Здесь говорится
TypeError: 'int' object is not iterable
Ответ №2:
возможно, это работает..
list = ['A','B','C',....]
i=-1
for entry in dataframe:
if entry['Race'] = 'W':
i =1
entry['new column'] = list[i]
также, если новый список столбцов очень большой для ввода, вы можете использовать понимание списка:
list = [x for x in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ']
Комментарии:
1. Вы
if entry['Race'] == 'W'
ошибаетесь. сама запись является Race.
Ответ №3:
Если ваш W, B, H
находится в этом точном порядке и завершает inteval, вы можете использовать np.repeat
. Как и в вашем комментарии, np.repeat
было бы достаточно только.
import numpy as np
a = ["A", "B", "C"] #list
n = df.Race.nunique() # length of each interval
df['New Col'] = np.repeat(a, n)
In [20]: df
Out[20]:
Race Boy Girl New Col
0 W 0 1 A
1 B 1 0 A
2 H 1 1 A
3 W 1 0 B
4 B 0 0 B
5 H 0 1 B
6 W 1 0 C
7 B 1 1 C
8 H 0 1 C
Комментарии:
1. Спасибо за вашу помощь, и да, они расположены в точном порядке, но вместо 3 (
W,H,B
) у меня их 17. Когда я запускаю код, он говоритValueError: Length of values does not match length of index
2. Я изменил 3 на 67, чтобы соответствовать длине моего списка, и 9 на 1139, чтобы соответствовать длине моего массива данных, но все равно получаю ту же ошибку
3. @Eniola может быть, проверьте мой ответ ниже (выше?)? мне любопытно, что дает вам ваши полные данные.
4. Длина интервала на самом деле равна 17, а длина всех данных равна 1139 (67*17).
5. @Eniola: если это так, работает ли это:
df['New Col'] = np.repeat(a, 17)
гдеa
находится список
Ответ №4:
Вот способ с pandas. Он увеличивается каждый раз, когда вы видите новый ‘W’ и обрабатывает недостающие значения Race.
# use original post's definition of df
df['New Col'] = (
(df['Race'] == 'W') # True (1) for W; False (0) otherwise
.cumsum() # increments each time you hit True (1)
.map({1: 'A', 2: 'B', 3: 'C'}) # 1->A, 2->B, ...
)
print(df)
Race Boy Girl New Col
0 W 0 1 A
1 B 1 0 A
2 H 1 1 A
3 W 1 0 B
4 B 0 0 B
5 H 0 1 B
6 W 1 0 C
7 B 1 1 C
8 H 0 1 C
Ответ №5:
Существует несколько способов решения этой проблемы. Вы можете выполнять итерации по фрейму данных и присваивать значения новому столбцу через каждый интервал.
Вот подход, который, я думаю, сработает.
#setting up the DataFrame you referred in the example
import pandas as pd
df = pd.DataFrame({'Race':['W','B','H','W','B','H','W','B','H'],
'Boy':[0,1,1,1,0,0,1,1,0],
'Girl':[1,0,1,0,0,1,0,1,1]})
#if you have 3 values to assign, create a list say A, B, C
#By creating a list, you have to manage only the list and the frequency
a = ['A','B','C']
#iterate thru the dataframe and assign the values in batches
for (i,row) in df.iterrows(): #the trick is to assign for loc[i]
df.loc[i,'New'] = a[int(i/3)] #where i is the index and assign value in list a
#note: dividing by 3 will distribute equally
print(df)
Результатом этого будет:
Race Boy Girl New
0 W 0 1 A
1 B 1 0 A
2 H 1 1 A
3 W 1 0 B
4 B 0 0 B
5 H 0 1 B
6 W 1 0 C
7 B 1 1 C
8 H 0 1 C
Я вижу, что вы пытаетесь получить решение, которое работает для 17 наборов записей. Вот код, и он работает правильно.
import pandas as pd
df = pd.DataFrame({'Race':['W','B','H']*17,
'Boy':[0,1,1]*17,
'Girl':[1,0,1]*17})
#in the DataFrame, you can define the Boy and Girl value
#I think Race values are repeating so I just repeated it 17 times
#define a variable from a thru z
a = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
for (i,row) in df.iterrows():
df.loc[i,'New'] = a[int(i/3)] #still dividing it by 3 equal batches
print(df)
Я не печатал для всех 17 наборов. Я только что сделал с 7 наборами. Результат все тот же.
Race Boy Girl New
0 W 0 1 A
1 B 1 0 A
2 H 1 1 A
3 W 0 1 B
4 B 1 0 B
5 H 1 1 B
6 W 0 1 C
7 B 1 0 C
8 H 1 1 C
9 W 0 1 D
10 B 1 0 D
11 H 1 1 D
12 W 0 1 E
13 B 1 0 E
14 H 1 1 E
15 W 0 1 F
16 B 1 0 F
17 H 1 1 F
18 W 0 1 G
19 B 1 0 G
20 H 1 1 G
Ответ №6:
Старый способ pythonic: используйте функцию!
In [18]: df
Out[18]:
Race Boy Girl
0 W 0 1
1 B 1 0
2 H 1 1
3 W 1 0
4 B 0 0
5 H 0 1
6 W 1 0
7 B 1 1
8 H 0 1
Функция:
def make_new_col(race_col, abc):
race_col = iter(race_col)
abc = iter(abc)
new_col = []
while True:
try:
race = next(race_col)
except:
break
if race == 'W':
abc_value = next(abc)
new_col.append(abc_value)
else:
new_col.append(abc_value)
return new_col
Затем выполните:
abc = ['A', 'B', 'C']
df['New Column'] = make_new_col(df['Race'], abc)
Вы получаете:
In [20]: df
Out[20]:
Race Boy Girl New Column
0 W 0 1 A
1 B 1 0 A
2 H 1 1 A
3 W 1 0 B
4 B 0 0 B
5 H 0 1 B
6 W 1 0 C
7 B 1 1 C
8 H 0 1 C
Комментарии:
1. Я запустил этот код, и я получил ошибку
StopIteration:
2. Ошибка возникает при
abc_value = next(countyNames)
3. @Eniola вероятно, это связано с тем, что число
W
s не равно числу A, B, C , … Можете ли вы перепроверить??4. Я также отредактировал функцию, чтобы вам не приходилось касаться ее внутри. Просто скопируйте вставку и укажите два аргумента:
df['Race']
иabc
соответственно вашим переменным.5. О!! я только что увидел реальную проблему. Это моя ошибка при копировании и вставке моего кода! Вы должны поместить
return new_col
на тот же уровень, что иwhile True
цикл.