Что возвращается из std :: vector :: data (), когда вектор пуст? [Дубликат]

В вашей ситуации наиболее простым было бы создать метки и интервалы вручную и применить это с помощью ax.xaxis.set_major_formatter.

Вот возможное решение:

Поскольку ни один образец данных не был

Настройка:

# imports
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as ticker

# A dataframe with random numbers ro run tests on
np.random.seed(123456)
rows = 100
df = pd.DataFrame(np.random.randint(-10,10,size=(rows, 1)), columns=['error'])
datelist = pd.date_range(pd.datetime(2017, 1, 1).strftime('%Y-%m-%d'), periods=rows).tolist()
df['dates'] = datelist 
df = df.set_index(['dates'])
df.index = pd.to_datetime(df.index)

test_df = df.copy(deep = True)

# Plot of data that mimics the structure of your dataset
ax = test_df[(test_df.index.year ==2017) ]['error'].plot(kind="bar")
ax.figure.autofmt_xdate()
plt.figure(figsize=(15,8))

Возможное решение:

test_df = df.copy(deep = True)
ax = test_df[(test_df.index.year ==2017) ]['error'].plot(kind="bar")
plt.figure(figsize=(15,8))

# Make a list of empty myLabels
myLabels = ['']*len(test_df.index)

# Set labels on every 20th element in myLabels
myLabels[::20] = [item.strftime('%Y - %m') for item in test_df.index[::20]]
ax.xaxis.set_major_formatter(ticker.FixedFormatter(myLabels))
plt.gcf().autofmt_xdate()

# Tilt the labels
plt.setp(ax.get_xticklabels(), rotation=30, fontsize=10)
plt.show()

Вы можете легко изменить форматирование меток, установив strftime.org

14
задан André 21 August 2014 в 08:47
поделиться

4 ответа

Соглашением для диапазонов является [inclusive, exclusive), то есть, если вы выполняете итерацию по диапазону [X,Y), вы концептуально выполните следующее (псевдокод):

for( iterator ii = X; ii != Y; ++ii) {
...
}

Это позволяет выразить пустой диапазон как [X,X). Кроме того, этот пустой диапазон отлично определен для каждого адреса, независимо от того, является ли он действительным или недействительным.

При этом требования к data() (внимание мое):

23.3.6.4 [vector.data]

T * data () noexcept;

const T * data () const noexcept;

Возвраты: указатель, для которого [data (), data () + size ()) является допустимым диапазоном. Для непустого вектора data () == & amp; front ().

Мне кажется, что единственная безусловная гарантия заключается в том, что [data(),data() + size()) должен быть допустимым диапазоном. Для функции size() == 0 функция-член data() может возвращать любое значение, и диапазон будет действительным пустым диапазоном. Поэтому я бы сказал, что реализации разрешено возвращать ненулевой указатель, если size() равно нулю .

12
ответ дан juanchopanza 25 August 2018 в 12:39
поделиться

Существует состояние, в котором объект может быть действительным, но неопределенным:

действительное, но неуказанное состояние [§ 17.3]

состояние объекта, которое не указано, за исключением того, что инварианты объекта выполняются, и операции над объектом ведут себя так, как указано для его типа

[ Пример: Если объект x типа std :: vector находится в действительном, но неуказанном состоянии , x.empty () можно назвать безоговорочно, а x.front () можно вызвать только в том случае, если x.empty () возвращает false. -end example ]

При чтении стандарта C ++ состояние data() не указывается, когда вектор пуст. Итак, состояние действительное, но неуказанное состояние . Поэтому возвращаемое значение data(), когда вектор пуст, может быть любым (нулевое или случайное значение). Это зависит от реализации компилятора.

В этом случае, следуя примеру в § 17.3, вы должны вызвать empty() перед использованием data(), чтобы убедиться, что возвращаемое значение является вашим ожиданием.

if (!v.empty())
   do_something(v.data())
0
ответ дан deepmax 25 August 2018 в 12:39
поделиться

Да, это возможно, и libstdc ++ делает это. Вы можете посмотреть документацию data () в libstdc ++

 data() _GLIBCXX_NOEXCEPT
 { return _M_data_ptr(this->_M_impl._M_start); }

Однако выполнение действий над этим указателем может не указываться, так как вы получаете доступ к не- инициализированный диапазон внутри вашего вектора, без его знаний (например, вы не знаете точный размер пакета памяти). Кроме того, поскольку size() равно 0, ваш допустимый диапазон все еще пуст.

0
ответ дан MatthiasB 25 August 2018 в 12:39
поделиться

Ни одна из формулировок в стандарте не предлагает заданное значение для данных (), если вектор пуст ().

И вот какое-то окончательное доказательство того, почему вы не должны предполагать, что оно может быть равно нулю, даже хотя иногда это:

#include <vector>
#include <iostream>


void value_of_data(std::vector<int> const& v)
{
    std::cout << "empty() = " << v.empty() << ", " << "data() = " << static_cast<const void*>(v.data()) << std::endl;
}



int main()
{
    std::vector<int> v;
    value_of_data(v);

    v.resize(100, 0);
    v.clear();
    value_of_data(v);
}

пример вывода (gcc7.2, -O2, linux):

empty() = 1, data() = 0
empty() = 1, data() = 0x7ebc30

http: //coliru.stacked-crooked .com / а / dd1d13200c8b9a3a

3
ответ дан Richard Hodges 25 August 2018 в 12:39
поделиться
Другие вопросы по тегам:

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