У меня есть файл CSV следующего формата
86,1
15,2
19,3
52,4
15,5
13,6
18,7
20,8
49,9
266,10
Для воспроизводимости я включил полный CSV-файл здесь. Из столбца 1 я хотел прочитать текущую строку и сравнить ее со значением предыдущей строки. Если оно больше, я хотел взять разницу текущего значения от предыдущего и сохранить (append) разницу в списке. Если текущее значение равно значению предыдущей строки, продолжайте сравнение. Поясню. Например, в приведенном выше образце записи, который я предоставил, третья строка (19) больше, чем значение во второй строке (15) - поэтому будет (19-15 =4), четвертая строка (52-19 = 33), и Т. Д.
Вот мой простой подход с использованием numpy
import numpy as np
import pandas as pd
import csv
df = pd.read_csv("testdata.csv")
with open("testdata.csv") as f:
reader = csv.reader(f, delimiter = ",")
for i in reader:
print (i[0])
diffs=np.diff(i[0])
increased_value=np.median(diffs[diffs>0])
Однако я получаю сообщение об ошибке IndexError: list assignment index out of range. Как я могу исправить эту ошибку, чтобы решить задачу, которую я упомянул?
НЕТ, в файле CSV НЕТ пустых строк.






Я думаю, что это лучший способ
df = pd.read_csv("testdata.csv", header=None)
df
0 1
0 86 1
1 15 2
2 19 3
3 52 4
4 15 5
5 13 6
6 18 7
7 20 8
8 49 9
9 266 10
diffs = np.diff(df[0])
increased_value = np.median(diffs[diffs>0])
increased_value
17.0
Это круто! Однако, если вы напечатаете diffs, он выдаст array([-71, 4, 33, -37, -2, 5, 2, 29, 217]). Как мы можем исключить отрицательные числа из списка? Поскольку я хочу, чтобы ТОЛЬКО текущее значение было больше, чем значение предыдущей строки.
diffs = diffs[diffs > 0], если вы хотите отбросить отрицательные значения, или diffs[diffs < 0] = 0, если вы хотите установить их равными нулю.
А если я хочу сделать наоборот? Значение, когда текущее значение строки равно less than предыдущему значению строки? Я сделал это так: np.median(diffs[diffs>0]), но значения списка массивов, которые я получаю, являются числами negative - [-71 -37 -2] -37.0
diffs = np.diff(df[0])*-1 возвращает` [ 71, -4, -33, 37, 2, -5, -2, -29, -217]` np.median(diffs[diffs>0]) должен возвращать 37.0 Это то, на что вы надеялись?
@AanayMital, НЕТ - растущая часть, как вы это сделали в своем ответе, верна. Но я пытался сделать противоположное заданному мной вопросу — что произойдет, если мы захотим сделать это, когда текущее значение будет smaller, чем предыдущее значение? Для этого (обратная часть) я ожидал получить [-71 -37 -2] и среднее значение -37.0.
да, это просто np.median(diffs[diffs<0]). Правильно?
По сути, np.diff() ожидает список, похожий на ввод, и то, что вы передаете, является целым числом. Вот почему это не удается
Нам технически не нужен numpy
from statistics import median
from operator import itemgetter, lt, sub
first = itemgetter(0)
nums = []
with open('testdata.csv', 'r') as fin:
reader = csv.reader(fin)
for line in reader:
nums.append(int(first(line)))
res = [abs(sub(*t)) for t in zip(nums, nums[1:]) if lt(*t)]
[4, 33, 5, 2, 29, 217]
median(res)
17.0
Но использование numpy, как показал Ананай Митал, в 99% случаев предпочтительнее использования списков для числовых данных.
это зависит от варианта использования, но сказать, что 99% случаев - это чрезмерный охват, эти небольшие данные тривиальны, мы можем согласиться не согласиться
Это здорово, но строка res = [abs(sub(*t)) for t in zip(nums, nums[1:]) if lt(*t)] говорит Invalid syntax на Python3.
@aws_apprentice, откуда 5 в списке [4, 33, 5, 2, 29, 217]? Я смущен. Если я сделаю это вручную, вместо этого я получу 5 значений.
@Brown предоставленные вами образцы данных имеют 13, а затем 18, следовательно, 5
Причина, по которой вы получаете
IndexError: list assignment index out of range
np.diff() принимает входные данные, такие как массив или список.
Нравится
arr = []
df = pd.read_csv("testdata3.csv")
df
with open("testdata3.csv", mode='r', encoding='utf-8-sig') as f:
reader = csv.reader(f, delimiter = ",")
for i in reader:
# print(i[0])
arr.append(int(i[0]))
diffs=abs(np.diff(arr))
increased_value=np.median(diffs[diffs>0])
А если я хочу сделать наоборот? Значение, когда текущее значение строки равно less than предыдущему значению строки? Я сделал это так: np.median(diffs[diffs>0]), но значения списка массивов, которые я получаю, являются числами negative - [-71 -37 -2] -37.0
Проблема, с которой вы столкнулись, заключается в том, что когда вы пытаетесь запустить np.diff, типом dtype по умолчанию для вашего массива является dtype U3, что означает, что значения в вашем массиве не являются числами, что означает, что требуется преобразование. Попробуйте следующее:
with open("test_data.csv", "r") as f:
reader = csv.reader(f) ## no need for delimiter if your delimiter is ','
data = []
for row in reader:
data.append(row[0])
## ensure that you convert your data into numpy array with appropriate data type
## before carrying out any mathematical operations
np_array = np.array(data, dtype=np.uint8)
np_diff = np.diff(np_array)
np_median = abs(np.median(np_diff[np_diff > 0]))
print(np_median)
Если вам нужно делать это регулярно, вы всегда можете обернуть этот метод вокруг. Попробуйте это.
А если я хочу сделать наоборот? Значение, когда текущее значение строки равно less than предыдущему значению строки? Я сделал это так: np.median(diffs[diffs>0]), но значения списка массивов, которые я получаю, являются числами negative - [-71 -37 -2] -37.0
Вы ожидаете, что ваш результат всегда будет положительным?
Да, я ожидаю, что все мои результаты будут положительными.
Я только что сделал обновление, чтобы включить abs в переменную np_median, что сделает все результаты положительными.
он печатает весь список array([185, 4, 33, 219, 254, 5, 2, 29, 217], dtype=uint8), что я не думаю, что это правильно. Для возрастающей части он должен вместо этого печатать только [4, 33, 5, 2, 29, 219]. Вопрос, который я задал в своем первом комментарии к вашему ответу, также должен печатать [-71 -37 -2].
Извините за задержку с ответом. Я только что попытался использовать обычный список, содержащий ваши числа, т.е. данные = [(86,1),(15,2),(19,3),(52,4), (15,5), (13,6), (18,7), (20,8),(49,9),(266,10)], а затем перебрали, чтобы получить список a = [86, 15, 19, 52, 15, 13, 18, 20 , 49, 266]. Затем я преобразовал это в массив numpy, а затем применил diff для получения массива ([185, 4, 33, 219, 254, 5, 2, 29, 217], dtype = uint8). С этого момента я использовал abs(np.median(np_diff[np_diff > 0])), что дает мне 33,0. Для вашего комментария о том, что текущее значение меньше предыдущего значения, вам нужно будет отсортировать ваши данные, т.е. отсортировать (данные).
diffs[diffs > 0] является только фильтром и на самом деле не сообщает вам, меньше ли текущее значение строки, чем значение предыдущей строки. Для этого вам нужно будет сделать петлю.
в вашем CSV-файле есть пустые строки?