среднее значение для указанных 1000 столбцов и сохранение их в новом столбце - PullRequest
1 голос
/ 29 февраля 2020

Что я здесь не так делаю? У меня есть фрейм данных, где я добавляю два новых столбца, первый создает счетчик, добавляя все значения в каждом столбце справа, которые равны 1. Эта часть работает нормально. Следующая часть кода должна давать среднее значение всех значений справа, которые не равны 0. По какой-то причине это также учитывает значения слева. Вот код Спасибо за любую помощь.

Я попробовал свой код, а также оба приведенных ниже решения, и все еще получаю неправильное среднее значение. Вот упрощенная версия со случайным фреймом данных и всеми тремя версиями кода. Я удалил значения слева и все еще имею проблему среднего значения, являющегося неправильным. Может быть, это поможет.

Версия 1:

df = pd.DataFrame(np.random.randint(0,3,size=(10, 10)), columns=list('ABCDEFGHIJ'))

idx_last = len(df.columns)
df.insert(loc=0, column='new', value=df[df[0:(idx_last+1)]==1].sum(axis=1))

idx_last = len(df.columns)
df.insert(loc=1, column='avg', value=df[df[0:(idx_last+1)]!=0].mean(axis=1))

df

Версия 2:

df = pd.DataFrame(np.random.randint(0,3,size=(10, 10)), columns=list('ABCDEFGHIJ'))

df.insert(loc=0, column='new', value=(df.iloc[:, 0:]==1).sum(axis=1))
df.insert(loc=1, column='avg', value=(df.iloc[:, 1:]!=0).mean(axis=1))

df

Версия 3:

df = pd.DataFrame(np.random.randint(0,3,size=(10, 10)), columns=list('ABCDEFGHIJ'))

idx_last = len(df.columns)
loc_value=0
df.insert(loc=loc_value, column='new', value=df[df[loc_value:(idx_last+1)]==1].sum(axis=1))

idx_last = len(df.columns)
loc_value=1
df.insert(loc=loc_value, column='avg', value=df[df[loc_value: (idx_last+1)]!=0].sum(axis=1))

df

Ответы [ 2 ]

3 голосов
/ 29 февраля 2020

Я полагаю, вам нужна функция DataFrame.iloc для получения столбцов по позициям, потому что добавляется новый столбец, необходимо использовать позицию + 1 для avg столбца с DataFrame.where для заменить несоответствующие значения на пропущенные значения:

np.random.seed(123)
df = pd.DataFrame(np.random.randint(0,3,size=(10, 5)), columns=list('ABCDE'))

df.insert(loc=0, column='new', value=(df.iloc[:, 0:]==1).sum(axis=1))
df.insert(loc=1, column='avg', value=(df.iloc[:, 1:].where(df.iloc[:, 1:]!=0)).mean(axis=1))
print (df)
   new       avg  A  B  C  D  E
0    1  1.750000  2  1  2  2  0
1    2  1.600000  2  2  1  2  1
2    2  1.500000  2  1  0  1  2
3    2  1.333333  1  0  2  0  1
4    1  1.500000  2  1  0  0  0
5    1  1.666667  0  1  2  0  2
6    2  1.000000  0  0  1  0  1
7    1  1.500000  0  0  0  2  1
8    2  1.600000  1  2  2  2  1
9    1  1.500000  0  0  2  1  0

Или использовать помощник DataFrame в df1 переменную:

np.random.seed(123)
df = pd.DataFrame(np.random.randint(0,3,size=(10, 5)), columns=list('ABCDE'))

df1 = df.copy()
df.insert(loc=0, column='new', value=(df1==1).sum(axis=1))
df.insert(loc=1, column='avg', value=df1.where(df1!=0).mean(axis=1))
print (df)
   new       avg  A  B  C  D  E
0    1  1.750000  2  1  2  2  0
1    2  1.600000  2  2  1  2  1
2    2  1.500000  2  1  0  1  2
3    2  1.333333  1  0  2  0  1
4    1  1.500000  2  1  0  0  0
5    1  1.666667  0  1  2  0  2
6    2  1.000000  0  0  1  0  1
7    1  1.500000  0  0  0  2  1
8    2  1.600000  1  2  2  2  1
9    1  1.500000  0  0  2  1  0
2 голосов
/ 29 февраля 2020

Проблема возникает с выражением (df.iloc[:, 1:]!=0).mean(axis=1). Это потому, что df.iloc[:, 1:]!=0 вернет матрицу логических значений, поскольку это выражение сравнения. Принятие среднего значения таких значений не даст среднего значения исходных значений, поскольку максимальное значение в такой матрице в любом случае будет равно 1. Следовательно, следующее будет работать (обратите внимание также на индексацию)

df = pd.DataFrame(np.random.randint(0,3,size=(10, 10)), columns=list('ABCDEFGHIJ')) 
df.insert(loc=0, column='new', value=(df.iloc[:, 0:]==1).sum(axis=1)) 
df.insert(loc=1, column='avg', value=(df.iloc[:, 1:]!=0).sum(axis=1))  #just keeping the count of non zeros
df["avg"]=df.iloc[:, 2:].sum(axis=1)/df["avg"]     
...