Как я преобразовываю Excel последовательное число даты в.NET DateTime?

Я нахожу, что для таких случаев, как правило, проще быть понятным в отношении столбцов, чем позволять пандам делать все автоматически. Э.Г.

ax1.scatter(data['runtime'], data['pixels'])

и

ax2.scatter(data['runtime'], data['segments'])

Для полного примера, демонстрирующего это:

import pandas as pd
import matplotlib.pyplot as plt
from pylab import figure, show, legend, ylabel

data = pd.DataFrame({'runtime': [0.079277, 0.045553, 0.002466, 0.016046, 0.009114,
                                 0.000799, 0.007617],
                     'pixels':  [1756374, 1221211, 8134, 339786, 214936, 506, 192800],
                     'segments':[12960, 5129, 1247, 6854, 1930, 218, 2949]})

## create the general figure
fig1 = figure()

ax1 = fig1.add_subplot(111)
ax1.scatter(data['runtime'], data['pixels'], label="Pixels", marker='.', color='k')

ax1.set_ylabel('Pixels')
ax1.set_xlabel('Runtime (s)')

ax2 = ax1.twinx()

ax2.scatter(data['runtime'], data['segments'], label="Segments", marker='.', color='r')
ax2.set_ylabel('Segments', color='r')
for tl in ax2.get_yticklabels():
    tl.set_color('r')
fig1.legend(bbox_to_anchor=(0.225,0.845))
plt.show()

Shared X example

Вы также можете отметить легенду, вы можете изменить местоположение по своему усмотрению, изменив кортеж bbox_to_anchor, документов

Редактировать

[ 1116] Если вам нужно покрасить в зависимости от состояния, вы можете сделать что-то вроде этого

import pandas as pd
import matplotlib.pyplot as plt
from pylab import figure, show, legend, ylabel
import matplotlib.lines as mlines

data = pd.DataFrame({'state':   ["Texas", "California", "Rhode Island", "Washington", 
                                 "Alabama", "District of Columbia", "Ohio"],
                     'runtime': [0.079277, 0.045553, 0.002466, 0.016046, 
                                 0.009114, 0.000799, 0.007617],
                     'pixels':  [1756374, 1221211, 8134, 339786, 214936, 506, 192800],
                     'segments':[12960, 5129, 1247, 6854, 1930, 218, 2949]})

## create the general figure
fig1 = figure()

ax1 = fig1.add_subplot(111)
ax2 = ax1.twinx()
for ii in range(len(data['state'])):
    ax1.scatter(data['runtime'][ii], data['pixels'][ii], 
                label=data['state'][ii], marker='.')
    ax2.scatter(data['runtime'][ii], data['segments'][ii], marker='+')
ax1.set_ylabel('Pixels')
ax1.set_xlabel('Runtime (s)')
legend = fig1.legend(bbox_to_anchor=(0.3,0.845))
m1 = mlines.Line2D([], [], color='black', linewidth = 0, marker='.', label='Pixels')
m2 = mlines.Line2D([], [], color='black', linewidth = 0, marker='+', label='Segments')
plt.legend(handles=[m1,m2], loc='lower right')


ax2.set_ylabel('Segments', color='r')
for tl in ax2.get_yticklabels():
    tl.set_color('r')
plt.show()

Example with coloring

70
задан David Basarab 7 April 2009 в 20:31
поделиться

3 ответа

Где 39938 количество дней с 01.01.1900?

В этом случае используйте библиотечную функцию платформы DateTime.FromOADate() .
Эта функция инкапсулирует все специфические особенности и делает проверку границ.

Для его исторической ценности вот возможная реализация:

(C#)

public static DateTime FromExcelSerialDate(int SerialDate)
{
    if (SerialDate > 59) SerialDate -= 1; //Excel/Lotus 2/29/1900 bug   
    return new DateTime(1899, 12, 31).AddDays(SerialDate);
}

VB

Public Shared Function FromExcelSerialDate(ByVal SerialDate As Integer) As DateTime
    If SerialDate > 59 Then SerialDate -= 1 ''// Excel/Lotus 2/29/1900 bug
    Return New DateTime(1899, 12, 31).AddDays(SerialDate)
End Function

[Обновление]:
Хм... Быстрый тест этого показывает, что это - на самом деле два выходных. Не уверенный, где различие.

Хорошо: проблема решена теперь. См. комментарии для деталей.

78
ответ дан Cee McSharpface - it 24 November 2019 в 13:12
поделиться

Мне проще использовать Метод FromOADate , например:

DateTime dt = DateTime.FromOADate(39938);

Использование этого кода dt - «05.05.2009».

160
ответ дан 24 November 2019 в 13:12
поделиться
void ExcelSerialDateToDMY(int nSerialDate, int &nDay, 
                          int &nMonth, int &nYear)
{
    // Excel/Lotus 123 have a bug with 29-02-1900. 1900 is not a
    // leap year, but Excel/Lotus 123 think it is...
    if (nSerialDate == 60)
    {
        nDay    = 29;
        nMonth    = 2;
        nYear    = 1900;

        return;
    }
    else if (nSerialDate < 60)
    {
        // Because of the 29-02-1900 bug, any serial date 
        // under 60 is one off... Compensate.
        nSerialDate++;
    }

    // Modified Julian to DMY calculation with an addition of 2415019
    int l = nSerialDate + 68569 + 2415019;
    int n = int(( 4 * l ) / 146097);
            l = l - int(( 146097 * n + 3 ) / 4);
    int i = int(( 4000 * ( l + 1 ) ) / 1461001);
        l = l - int(( 1461 * i ) / 4) + 31;
    int j = int(( 80 * l ) / 2447);
     nDay = l - int(( 2447 * j ) / 80);
        l = int(j / 11);
        nMonth = j + 2 - ( 12 * l );
    nYear = 100 * ( n - 49 ) + i + l;
}

Вырезать и вставить чужие таланты ...

Ян Браун

1
ответ дан 24 November 2019 в 13:12
поделиться
Другие вопросы по тегам:

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