Определите и примените пользовательские ячейки на фрейме данных

Другой способ, которым мы это делаем, - collections.Counter. Второй ответ L3viathan - самый эффективный и быстрый способ сделать это.

def sublist1(lst1, lst2):
    ls1 = [element for element in lst1 if element in lst2]
    ls2 = [element for element in lst2 if element in lst1]
    return ls1 == ls2


def sublist2(lst1, lst2):
    def get_all_in(one, another):
        for element in one:
            if element in another:
                yield element
    for x1, x2 in zip(get_all_in(lst1, lst2), get_all_in(lst2, lst1)):
        if x1 != x2:
            return False
    return True


def sublist3(lst1, lst2):
    from collections import Counter
    c1 = Counter(lst1)
    c2 = Counter(lst2)
    for item, count in c1.items():
        if count > c2[item]:
            return False
    return True


l1 = ["a", "b", "c", "c", "c", "d", "e"]
l2 = ["c", "a", "c", "b", "c", "c", "d", "d", "f", "e"]

s1 = lambda: sublist1(l1, l2)
s2 = lambda: sublist2(l1, l2)
s3 = lambda: sublist3(l1, l2)

from timeit import Timer
t1, t2, t3 = Timer(s1), Timer(s2), Timer(s3)
print(t1.timeit(number=10000))  # => 0.034193423241588035
print(t2.timeit(number=10000))  # => 0.012621842119714115
print(t3.timeit(number=10000))  # => 0.12714286673722477

Его второй способ быстрее на порядок, но я хотел упомянуть вариант Counter из-за его распространенности и использования вне этого сценария.

29
задан smci 17 September 2018 в 03:15
поделиться

4 ответа

Другой ответ обрезки, учитывающий экстремумы:

dat <- read.table("clipboard", header=TRUE)

cuts <- apply(dat, 2, cut, c(-Inf,seq(0.5, 1, 0.1), Inf), labels=0:6)
cuts[cuts=="6"] <- "0"
cuts <- as.data.frame(cuts)

  cosinFcolor cosinEdge cosinTexture histoFcolor histoEdge histoTexture jaccard
1           3         0            0           1         1            0       0
2           0         0            5           0         2            2       0
3           1         0            2           0         0            1       0
4           0         0            3           0         1            1       0
5           1         3            1           0         4            0       0
6           0         0            1           0         0            0       0

Объяснение

Функция обрезки разбивается на ячейки в зависимости от заданных срезов. Итак, давайте возьмем 1:10 и разделим его на 3, 5 и 7.

cut(1:10, c(3, 5, 7))
 [1] <NA>  <NA>  <NA>  (3,5] (3,5] (5,7] (5,7] <NA>  <NA>  <NA> 
Levels: (3,5] (5,7]

Вы можете видеть, как это привело к тому, что уровни находятся между перерывами. Также обратите внимание, что он не включает 3 (есть аргумент include.lowest, который будет включать его). Но это ужасные названия для групп, давайте назовем их группами 1 и 2.

cut(1:10, c(3, 5, 7), labels=1:2)
 [1] <NA> <NA> <NA> 1    1    2    2    <NA> <NA> <NA>

Лучше, но что там с АН? Они находятся за пределами наших границ и не учитываются. Чтобы подсчитать их, в своем решении я добавил -infinity и infinity, чтобы все точки были включены. Обратите внимание, что, поскольку у нас больше перерывов, нам понадобится больше меток:

x <- cut(1:10, c(-Inf, 3, 5, 7, Inf), labels=1:4)
 [1] 1 1 1 2 2 3 3 4 4 4
Levels: 1 2 3 4

Хорошо, но мы не хотели 4 (в соответствии с вашей проблемой). Мы хотели, чтобы все четверки были в группе 1. Итак, давайте избавимся от записей, которые помечены как «4».

x[x=="4"] <- "1"
 [1] 1 1 1 2 2 3 3 1 1 1
Levels: 1 2 3 4

Это немного отличается от того, что я делал раньше, обратите внимание, что я убрал все последние ярлыки в конце, но я сделал это вот так, чтобы вы могли лучше увидеть, как работает cut.

Хорошо, функция apply. До сих пор мы использовали разрез на одном векторе. Но вы хотите, чтобы он использовался для набора векторов: каждого столбца вашего фрейма данных. Это то, что делает второй аргумент из apply. 1 применяет функцию ко всем строкам, 2 применяется ко всем столбцам. Примените функцию cut к каждому столбцу вашего фрейма данных. Все, что после cut в функции apply, является просто аргументами для cut, о котором мы говорили выше.

Надеюсь, что помогает.

53
ответ дан sebastian-c 17 September 2018 в 03:15
поделиться

С разрезом это просто, как пирог

dtf <- read.table(
textConnection(
"cosinFcolor cosinEdge cosinTexture histoFcolor histoEdge histoTexture jaccard
1 0.770 0.489 0.388 0.57500000 0.5845137 0.3920000 0.00000000
2 0.067 0.496 0.912 0.13865546 0.6147309 0.6984127 0.00000000
3 0.514 0.426 0.692 0.36440678 0.4787535 0.5198413 0.05882353
4 0.102 0.430 0.739 0.11297071 0.5288008 0.5436508 0.00000000
5 0.560 0.735 0.554 0.48148148 0.8168083 0.4603175 0.00000000
6 0.029 0.302 0.558 0.08547009 0.3928234 0.4603175 0.00000000"), sep = " ", 
           header = TRUE)

dtf$bin <- cut(dtf$cosinFcolor, breaks = c(0, seq(0.5, 1, by = .1)), labels = 0:5)
dtf
  cosinFcolor cosinEdge cosinTexture histoFcolor histoEdge histoTexture    jaccard bin
1       0.770     0.489        0.388  0.57500000 0.5845137    0.3920000 0.00000000   3
2       0.067     0.496        0.912  0.13865546 0.6147309    0.6984127 0.00000000   0
3       0.514     0.426        0.692  0.36440678 0.4787535    0.5198413 0.05882353   1
4       0.102     0.430        0.739  0.11297071 0.5288008    0.5436508 0.00000000   0
5       0.560     0.735        0.554  0.48148148 0.8168083    0.4603175 0.00000000   1
6       0.029     0.302        0.558  0.08547009 0.3928234    0.4603175 0.00000000   0
14
ответ дан Luciano Selzer 17 September 2018 в 03:15
поделиться

Вот еще одно решение, использующее функцию bin_data() из пакета mltools .

Биннинг одного вектора

library(mltools)

cosinFcolor <- c(0.77, 0.067, 0.514, 0.102, 0.56, 0.029)
binned <- bin_data(cosinFcolor, bins=c(0, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0), boundaryType = "[lorc")

binned
[1] (0.7, 0.8] [0, 0.5]   (0.5, 0.6] [0, 0.5]   (0.5, 0.6] [0, 0.5]  
Levels: [0, 0.5] < (0.5, 0.6] < (0.6, 0.7] < (0.7, 0.8] < (0.8, 0.9] < (0.9, 1]

# Convert to numbers 0, 1, ...
as.integer(binned) - 1L

Биннинг каждого столбца в data.frame

df <- read.table(textConnection(
  "cosinFcolor cosinEdge cosinTexture histoFcolor histoEdge histoTexture jaccard
0.770 0.489 0.388 0.57500000 0.5845137 0.3920000 0.00000000
0.067 0.496 0.912 0.13865546 0.6147309 0.6984127 0.00000000
0.514 0.426 0.692 0.36440678 0.4787535 0.5198413 0.05882353
0.102 0.430 0.739 0.11297071 0.5288008 0.5436508 0.00000000
0.560 0.735 0.554 0.48148148 0.8168083 0.4603175 0.00000000
0.029 0.302 0.558 0.08547009 0.3928234 0.4603175 0.00000000"
), sep = " ", header = TRUE)

for(col in colnames(df)) df[[col]] <- as.integer(bin_data(df[[col]], bins=c(0, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0), boundaryType = "[lorc")) - 1L

df
  cosinFcolor cosinEdge cosinTexture histoFcolor histoEdge histoTexture jaccard
1           3         0            0           1         1            0       0
2           0         0            5           0         2            2       0
3           1         0            2           0         0            1       0
4           0         0            3           0         1            1       0
5           1         3            1           0         4            0       0
6           0         0            1           0         0            0       0
2
ответ дан Ben 17 September 2018 в 03:15
поделиться

Вы также можете использовать findInterval:

findInterval(seq(0, 1, l=20), seq(0.5, 1, by=0.1))

## [1] 0 0 0 0 0 0 0 0 0 1 1 2 2 3 4 4 5 5
24
ответ дан sebastian-c 17 September 2018 в 03:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: