Быстро получить строки с максимальным значением для каждого индикатора в большой data.table - PullRequest
0 голосов
/ 03 июля 2019

Мне дан большой файл данных, например,

n <- 7
dt <- data.table(id_1=sample(1:10^(n-1),10^n,replace=TRUE), other=sample(letters[1:20],10^n,replace=TRUE), val=rnorm(10^n,mean=10^4,sd=1000))

> structure(dt)
        id_1 other       val

    1: 914718     o  9623.078  
    2: 695164     f 10323.943
    3:  53186     h 10930.825
    4: 496575     p  9964.064
    5: 474733     l 10759.779
   ---                       
9999996: 650001     p  9653.125
9999997: 225775     i  8945.636
9999998: 372827     d  8947.095
9999999: 268678     e  8371.433
10000000: 730810     i 10150.311

и я хотел бы создать таблицу data.table, в которой для каждого значения индикатора id_1 имеется только одна строка, а именно та, которая имеет наибольшее значение в столбце val.

Кажется, работает следующий код:

dt[, .SD[which.max(val)], by = .(id_1)]

Тем не менее, это очень медленно для больших таблиц. Есть ли более быстрый способ?

Ответы [ 2 ]

0 голосов
/ 04 июля 2019

Технически, это дубликат этого вопроса , но ответ не был действительно объяснен, так что здесь идет:

dt[dt[, .(which_max = .I[val == max(val)]), by = "id_1"]$which_max]

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

Тем не менее, я немного удивлен, что не нашел ответа на этот вопрос:

setkey(dt, id_1, val)[, .SD[.N], by = "id_1"]

, который, кажется, так же быстро в моей машине, но для этого нужно отсортировать строки.

0 голосов
/ 03 июля 2019

Я не уверен, как это сделать в R, но то, что я сделал, это прочитал строку за строкой и затем поместил эти строки во фрейм данных. Это очень быстро и происходит мгновенно для текстового файла размером 100 МБ.

import pandas as pd
filename ="C:/Users/xyz/Downloads/123456789.012-01-433.txt"
filename =filename

with open(filename, 'r') as f:
    sample =[]          #creating an empty array
    for line in f:
        tag=line[:45].split('|')[5] # its a condition, you dont need this.
        if tag == 'KV-C901':
            sample.append(line.split('|')) # writing those lines to an array table

print('arrays are appended and ready to create a dataframe out of an array') 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...