Я импортировал данные из CSV-файла в свою программу, а затем использовал set_index, чтобы установить «rule_id» в качестве индекса. Я использовал этот код:
df = pd.read_excel('stack.xlsx')
df.set_index(['rule_id'])
и данные выглядят так:
Теперь я хочу сравнить один столбец с другим, но в обратном порядке, например: Я хочу сравнить данные «c» с «b», затем сравнить «b» с «a» и т. д. и создать еще один столбец после сравнения, который содержит индекс столбца, где значение было равно нулю. Если оба столбца имеют значение 0 , то Null должен быть обновлен в новом столбце, а если оба значения сравнения отличны от 0 , то Null также должен быть обновлен в новом столбце. Результат должен выглядеть так:
Я не могу написать код, как мне подойти к этой проблеме, если бы вы, ребята, могли бы мне помочь, это было бы здорово.
Обновлено: Незначительное редактирование. Я импортировал данные из Excel, которые выглядят так, это всего лишь часть данных, есть несколько столбцов:
Затем я использовал сводную_таблицу для управления данными в соответствии с моим требованием, используя этот код:
df = df.pivot_table(index = 'rule_id' , columns = ['date'], values = 'rid_fc', fill_value = 0)
и мои данные теперь выглядят так:
Теперь я хочу сравнить один столбец с другим, но в обратном порядке, например: Я хочу сравнить данные «2019-04-25 16:36:32» с «2019-04-25 16:29:05», а затем сравнить «2019-04-25 16:29:05» с «2019-04». -25 16:14:14' и т. д. и создать еще один столбец после сравнения, который содержит индекс столбца, где значение было равно нулю. Если оба столбца имеют значение 0 , то Null должен быть обновлен в новом столбце, а если оба значения сравнения отличны от 0 , то Null также должен быть обновлен в новом столбце.
Вы можете использовать этот фрагмент кода. У меня не было времени усовершенствовать его с помощью петель и т. д., поэтому, пожалуйста, внесите изменения в соответствии с требованиями.
import pandas as pd
import numpy as np
# Data
print(df.head())
a b c
0 0 7 6
1 0 0 1
2 0 2 2
cp = df.copy()
cp[cp != 0] = 1
cp['comp1'] = cp['a'] + cp['b']
cp['comp2'] = cp['b'] + cp['c']
# Logic
cp = cp.replace([0, 1, 2], [1, np.nan, 0])
cp[['a', 'b', 'c']] = df[['a', 'b', 'c']]
# Results
print(cp.head())
a b c comp1 comp2
0 0 7 6 NaN 0.0
1 0 0 1 1.0 NaN
2 0 2 2 NaN 0.0
IIUC вы можете попробовать с:
d = {i:e for e,i in enumerate(df.columns)}
m1=df[['c','b']]
m2=df[['b','a']]
df['comp1']=m1.eq(0).dot(m1.columns).map(d)
m3=m2.eq(0).dot(m2.columns)
m3.loc[m3.str.len()!=1]=np.nan
df['comp2']=m3.map(d)
print(df)
a b c comp1 comp2
rule_id
51234 0 7 6 NaN 0.0
53219 0 0 1 1.0 NaN
56195 0 2 2 NaN 0.0
Я предлагаю использовать numpy - сравнить сдвинутые значения с logical_and
и установить новые столбцы по диапазону, созданному np.arange
с порядком перестановки и numpy.where
с конструктором DatFrame:
df = pd.DataFrame({
'a':[0,0,0],
'b':[7,0,2],
'c':[6,1,2],
})
#change order of array
x = df.values[:, ::-1]
#compare for equal 0 and and not equal 0
a = np.logical_and(x[:, 1:] == 0, x[:, :-1] != 0)
#create range from top to 0
b = np.arange(a.shape[1]-1, -1, -1)
#new columns names
c = [f'comp{i+1}' for i in range(x.shape[1] - 1)]
#set values by boolean array a and set values
df1 = pd.DataFrame(np.where(a, b[None, :], np.nan), columns=c, index=df.index)
print (df1)
comp1 comp2
0 NaN 0.0
1 1.0 NaN
2 NaN 0.0
Привет @jezrael, я получаю эту ошибку, когда использую ваш код: «столбцы перекрываются, но не указан суффикс: Index(['comp1', 'comp2', 'comp3'], dtype='object') ', а также у вас есть использовал np.where() и в том, что вы использовали имена столбцов как «a», «b», «c», но я просто использовал их только для удобства чтения, мои исходные столбцы выглядят так: 2019-04-25 16 :14:14
@vesuvius - Ошибка означает, что столбцы уже были раньше, поэтому необходимо df = df.join(df1, lsuffix='_new')
Да, мой плохой, извините. Но я все еще не получаю желаемого результата, я получаю 0 и Null везде, а также три столбца comp, в отличие от вашего результата @jezrael
@vesuvius - Так что, если нужно заменить только 3 столбца x = df.values
на x = df[['a','b','c']].values
- укажите имена столбцов в списке
Я получил результат, но я использовал «a», «b», «c» только для удобства, и у меня есть несколько столбцов, которые выглядят так: 2019-04-25 16:14:14, так что это не будет Я могу каждый раз упоминать столбцы, не могли бы вы предложить какие-то другие изменения, извините за расширение.
@vesuvius - первый вопрос - нужно работать только с 3 столбцами или со многими столбцами?
У меня есть несколько столбцов, которые выглядят как комбинация даты и метки времени.
@vesuvius - Так что, может быть, вы не уверены, понимаете ли вы, что нужно, возможно ли добавить 2-3 новых столбца с ожидаемым выводом и такие столбцы, как нужно, в ваши данные? Потому что, возможно, в моем решении что-то не так, но я не уверен, как лучше всего это проверить.
Я обновил свой вопрос @jezrael, это мои исходные данные
Давайте продолжить обсуждение в чате.
Привет, @skillsmuggler, у меня есть несколько столбцов, поэтому я не смогу каждый раз объявлять новый столбец с именем «comp». Можете ли вы предложить что-то еще, я думаю об использовании columns=lambda x: 'comp{}'.format(x+1), чтобы избавиться от этой проблемы.