Pythonic, эквивалентный из несдвига или восстановления?

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

Оба графика имеют одинаковую ось Y, и пациенты в группе риска представлены с соответствующими значениями X.

Больше примеров здесь: https://github.com/Ashafix/Kaplan-Meier_Plotly

Пример 1 - Рак легких у женщин и мужчин [ 1110]

import pandas as pd
import lifelines
import plotly
import numpy as np
plotly.offline.init_notebook_mode()

df = pd.read_csv('http://www-eio.upc.edu/~pau/cms/rdata/csv/survival/lung.csv')

fig = plotly.tools.make_subplots(rows=2, cols=1, print_grid=False)
kmfs = []

dict_sex = {1: 'Male', 2: 'Female'}

steps = 5 # the number of time points where number of patients at risk which should be shown

x_min = 0 # min value in x-axis, used to make sure that both plots have the same range
x_max = 0 # max value in x-axis

for sex in df.sex.unique():
    T = df[df.sex == sex]["time"]
    E = df[df.sex == sex]["status"]
    kmf = lifelines.KaplanMeierFitter()

    kmf.fit(T, event_observed=E)
    kmfs.append(kmf)
    x_max = max(x_max, max(kmf.event_table.index))
    x_min = min(x_min, min(kmf.event_table.index))
    fig.append_trace(plotly.graph_objs.Scatter(x=kmf.survival_function_.index,
                                               y=kmf.survival_function_.values.flatten(),  
                                               name=dict_sex[sex]), 
                     1, 1)


for s, sex in enumerate(df.sex.unique()):
    x = []
    kmf = kmfs[s].event_table
    for i in range(0, int(x_max), int(x_max / (steps - 1))):
        x.append(kmf.iloc[np.abs(kmf.index - i).argsort()[0]].name)
    fig.append_trace(plotly.graph_objs.Scatter(x=x, 
                                               y=[dict_sex[sex]] * len(x), 
                                               text=[kmfs[s].event_table[kmfs[s].event_table.index == t].at_risk.values[0] for t in x], 
                                               mode='text', 
                                               showlegend=False), 
                     2, 1)

# just a dummy line used as a spacer/header
t = [''] * len(x)
t[1] = 'Patients at risk'
fig.append_trace(plotly.graph_objs.Scatter(x=x, 
                                           y=[''] * len(x), 
                                           text=t,
                                           mode='text', 
                                           showlegend=False), 
                 2, 1)


# prettier layout
x_axis_range = [x_min - x_max * 0.05, x_max * 1.05]
fig['layout']['xaxis2']['visible'] = False
fig['layout']['xaxis2']['range'] = x_axis_range
fig['layout']['xaxis']['range'] = x_axis_range
fig['layout']['yaxis']['domain'] = [0.4, 1]
fig['layout']['yaxis2']['domain'] = [0.0, 0.3]
fig['layout']['yaxis2']['showgrid'] = False
fig['layout']['yaxis']['showgrid'] = False

plotly.offline.iplot(fig)

enter image description here Пример 2 - Рак толстой кишки при различных методах лечения

df = pd.read_csv('http://www-eio.upc.edu/~pau/cms/rdata/csv/survival/colon.csv')

fig = plotly.tools.make_subplots(rows=2, cols=1, print_grid=False)
kmfs = []

steps = 5 # the number of time points where number of patients at risk which should be shown

x_min = 0 # min value in x-axis, used to make sure that both plots have the same range
x_max = 0 # max value in x-axis

for rx in df.rx.unique():
    T = df[df.rx == rx]["time"]
    E = df[df.rx == rx]["status"]
    kmf = lifelines.KaplanMeierFitter()

    kmf.fit(T, event_observed=E)
    kmfs.append(kmf)
    x_max = max(x_max, max(kmf.event_table.index))
    x_min = min(x_min, min(kmf.event_table.index))
    fig.append_trace(plotly.graph_objs.Scatter(x=kmf.survival_function_.index,
                                               y=kmf.survival_function_.values.flatten(),
                                               name=rx), 
                     1, 1)


fig_patients = []
for s, rx in enumerate(df.rx.unique()):
    kmf = kmfs[s].event_table
    x = []
    for i in range(0, int(x_max), int(x_max / (steps - 1))):
        x.append(kmf.iloc[np.abs(kmf.index - i).argsort()[0]].name)
    fig.append_trace(plotly.graph_objs.Scatter(x=x, 
                                               y=[rx] * len(x), 
                                               text=[kmfs[s].event_table[kmfs[s].event_table.index == t].at_risk.values[0] for t in x], 
                                               mode='text', 
                                               showlegend=False), 
                     2, 1)

# just a dummy line used as a spacer/header
t = [''] * len(x)
t[1] = 'Patients at risk'
fig.append_trace(plotly.graph_objs.Scatter(x=x, 
                                           y=[''] * len(x), 
                                           text=t,
                                           mode='text', 
                                           showlegend=False), 
                 2, 1)


# prettier layout
x_axis_range = [x_min - x_max * 0.05, x_max * 1.05]
fig['layout']['xaxis2']['visible'] = False
fig['layout']['xaxis2']['range'] = x_axis_range
fig['layout']['xaxis']['range'] = x_axis_range
fig['layout']['yaxis']['domain'] = [0.4, 1]
fig['layout']['yaxis2']['domain'] = [0.0, 0.3]
fig['layout']['yaxis2']['showgrid'] = False
fig['layout']['yaxis']['showgrid'] = False

plotly.offline.iplot(fig)

enter image description here [ 116]

12
задан Bill Karwin 7 January 2009 в 01:59
поделиться

7 ответов

Почему беспокойство с несмещением, когда выражение else должно всегда происходить?

for apple in tree:
    if (apple.weight + basket.weight) > 10:
       send(basket)
       basket.clear()
    basket.add(apple)

Так или иначе я вполне уверен, что Python не имеет вида поведения, которое Вы ищете.

13
ответ дан 2 December 2019 в 03:33
поделиться

Я изучаю Python, и у меня есть ситуация, где я хочу использовать объекты от итератора. Хитрая часть что происходит в определенных условиях, я хочу "не выполнить итерации". Таким образом, отложите объект на переднюю сторону итератора, прежде чем я циклично выполнюсь.

Вот простое решение:

class MyIterator(object):   # undo-able iterator wrapper
    def __init__(self, iterable):
        super(MyIterator, self).__init__()
        self.iterator = iter(iterable)
        self.stack = []

    def __iter__(self):
        return self

    def next(self):
        if self.stack:
            return self.stack.pop()
        return self.iterator.next()  # Raises StopIteration eventually

    def undo(self, item):
        self.stack.append(item)
for i in  MyIterator(xrange(5)): print i
0
1
2
3
4
rng = MyIterator(xrange(5))
rng.next()
0
rng.next()
1
rng.undo(1)
rng.next()
1
16
ответ дан 2 December 2019 в 03:33
поделиться

Я сказал бы, что большей частью решения Pythonic является самое простое. Вместо того, чтобы пытаться перенести итератор в выражение генератора, которое позволяет Вам "отслеживать в обратном порядке" или что-то столь же сложное, используйте некоторое время цикл, как Вы имеете в Perl! Итераторы не смешиваются очень приятно с мутацией, anywho.

Простой перевод Вашей реализации (игнорирующий оптимизацию @Patrick):

while tree:
    apple = tree.pop(0)
    if apple.weight + basket.weight > 10:
        basket.send()
        basket.clear()
        tree.insert(0, apple) # Put it back.
    else:
        basket.append(apple)

Или, Вы могли использовать a peek- как функциональность с заказанными индексами последовательности:

while tree:
    apple = tree[0] # Take a peek at it.
    if apple.weight + basket.weight > 10:
        basket.send()
        basket.clear()
    else:
        basket.append(tree.pop(0))

Если Вам не нравится "простой" аргумент, проверьте collections.deque итераторы упоминаются в вышеупомянутом (связанном) потоке.

6
ответ дан 2 December 2019 в 03:33
поделиться

Если Вы не хотите следовать за предложением других просто удаления выражения else, можно записать собственное unshift функция, которая будет работать в некотором роде подобная perl's с любым повторяемым:

class UnshiftableIterable(object):
    def __init__(self, iterable):
        self._iter = iter(iterable)
        self._unshifted = [] # empty list of unshifted stuff
    def __iter__(self):
        while True:
            if self._unshifted:
                yield self._unshifted.pop()
            else:
                yield self._iter.next()
    def unshift(self, item):
        self._unshifted.append(item)

Затем в Вашем коде:

it = UnshiftableIterable(tree)
for apple in tree:
    if weigth(basket) + weight(apple) > MAX_WEIGHT:
        send(basket)
        basket = []
        it.unshift(apple)
    else:
        basket.append(apple)

Некоторое тестирование UnshiftableIterable:

it = UnshiftableIterable(xrange(5))

for i in it:
    print '*',
    if i == 2:
        it.unshift(10)
    else:
        print i,
# output: * 0 * 1 * * 10 * 3 * 4
4
ответ дан 2 December 2019 в 03:33
поделиться

Нет никакого пути общего способа продвинуть значение в итератор в Python. Стек или связанный список лучше подходят для этого.

Если Вы выполняете итерации по списку или чему-то, конечно, можно добавить объект вручную назад к списку. Но можно также выполнить итерации по объектам, которыми нельзя управлять таким способом.

Если Вы хотите использовать Python для реализации того алгоритма, необходимо будет выбрать структуру данных, которая позволяет операции, которые Вы хотите использовать. Я предлагаю .push() и .pop() методы, которые позволяют Вам рассматривать списки как стеки.

-2
ответ дан 2 December 2019 в 03:33
поделиться

Вы ищете генератор, итератор, который может получить модификации к его внутреннему состоянию через отправление () метод

https://docs.python.org/howto/functional.html#passing-values-into-a-generator

3
ответ дан 2 December 2019 в 03:33
поделиться

В то время как я писал, что этот @Patrick уже предложил то же самое. Но так как я записал это, я вставлю код так или иначе с комментариями в методах выделения кода от Patrick.

import random

apples=[random.randint(1,3) for j in range(10)]
print 'apples',apples

basket=[]
y=6
baskets=[]

for i in range(len(apples)):
    if sum(basket+[apples[i]])>y:
        #basket is full                                                                                                                                     
        baskets.append(basket)#basket.send()                                                                                                                
        basket=[]#basket.empty()                                                                                                                            
    basket.append(apples[i])#add apple to basket                                                                                                            

print 'baskets',baskets

хотя это не выталкивает () яблоки от исходного итератора. Отметьте, является ли это желаемым поведением также.

вывод

apples [1, 1, 3, 3, 1, 1, 3, 3, 2, 3]
baskets [[1, 1, 3], [3, 1, 1], [3, 3]]
1
ответ дан 2 December 2019 в 03:33
поделиться
Другие вопросы по тегам:

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