станд.:: скопируйте в станд.:: суд для станд.:: пара

Предположим, у вас есть серия timedelta:

import pandas as pd
from datetime import datetime
z = pd.DataFrame({'a':[datetime.strptime('20150101', '%Y%m%d')],'b':[datetime.strptime('20140601', '%Y%m%d')]})

td_series = (z['a'] - z['b'])

. Один из способов конвертировать этот timedelta-столбец или серию - это передать его объекту Timedelta (pandas 0.15.0+), а затем извлечь дни из объект:

td_series.astype(pd.Timedelta).apply(lambda l: l.days)

Другой способ состоит в том, чтобы вывести серию как timedelta64 в днях, а затем передать ее как int:

td_series.astype('timedelta64[D]').astype(int)
16
задан Serge 11 March 2009 в 12:38
поделиться

6 ответов

Я основал один новый изящный способ решить эту проблему.
у меня есть много идей интереса когда прочитанные ответы:

  • итератор обертки, для станд. преобразования:: пара к станд.:: строка;
  • станд. обертки:: пара, для имеют шанс перегрузить operator< < (...);
  • используют обычный станд.:: for_each с печатью функтора;
  • станд. использования:: for_each с повышением:: labda - выглядит хорошим, кроме доступа к станд.:: pair<>:: сначала и станд.:: pair<>:: вторые участники;

я думаю, что буду использовать все это, идеи в будущем для решают различные другие проблемы.
, Но для этого случая я преуменьшил это, я могу сформулировать свой bproblem, поскольку "преобразовывают данные карты к строкам и пишут им в поток вывода" вместо этого, "копируют данные карты в ouput поток". Мое решение похоже:

namespace
{
std::string toString( const std::pair< size_t, size_t >& data)
{
    std::ostringstream str;
    str << data.first << ", " << data.second;
    return str.str();
}
} // namespace anonymous

std::transform( 
    some_map.begin(), 
    some_map.end(), 
    std::ostream_iterator< std::string >( std::cout, "\n" ),
    toString );

я думаю, что этот метод является самым коротким и выразительным, чем другие.

14
ответ дан 30 November 2019 в 15:30
поделиться

Нет никакого стандартного способа ухаживать std::pair, потому что, ну, в общем, то, как Вы хотите распечатанный, вероятно, отличается от способа, которым следующий парень хочет это. Это - хороший вариант использования для пользовательского функтора или функции лямбды. Можно тогда передать это как аргумент std::for_each, чтобы сделать работу.

typedef std::map<size_t, size_t> MyMap;

template <class T>
struct PrintMyMap : public std::unary_function<T, void>
{
    std::ostream& os;
    PrintMyMap(std::ostream& strm) : os(strm) {}

    void operator()(const T& elem) const
    {
        os << elem.first << ", " << elem.second << "\n";
    }
}

Для вызова этого функтора от кода:

std::for_each(some_map.begin(),
              some_map.end(),
              PrintMyMap<MyMap::value_type>(std::cout));
16
ответ дан 30 November 2019 в 15:30
поделиться

Я был бы точно так же, как, чтобы указать что добавление вещей к станд.:: пространство имен недопустимо согласно Стандарту C++ (см. раздел 17.4.3.1).

10
ответ дан 30 November 2019 в 15:30
поделиться

То, что Вы хотите, является итератором преобразования. Этот вид итератора обертывает другой итератор, вперед все методы расположения как оператор ++ и оператор ==, но переопределяет оператор* и оператор->.

Быстрый эскиз:

template <typename ITER> 
struct transformingIterator : private ITER {
    transformingIterator(ITER const& base) : ITER(base) {}
    transformingIterator& operator++() { ITER::operator++(); return *this; }
    std::string operator*() const
    {
        ITER::value_type const& v = ITER::operator*();
        return "[" + v->first +", " + v->second + "]";
    }
...
5
ответ дан 30 November 2019 в 15:30
поделиться

Используя Лямбду Повышения, Вы могли попробовать что-то вроде этого. Версия, которую я имею Лямбды Повышения, это на самом деле не работает, я протестирую и зафиксирую позже.

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

using namespace boost::lambda;

std::for_each( some_map.begin(), some_map.end(), 
               std::cout << bind( &std::map<size_t,size_t>::value_type::first, _1 )
                         << ","
                         << bind( &std::map<size_t,size_t>::value_type::second, _1 ) );
2
ответ дан 30 November 2019 в 15:30
поделиться

[Я удалил бы этот ответ, но я оставлю его на данный момент, в случае, если кто-то находит обсуждение интересным.]

<забастовка>, Так как это - разумное расширение библиотеки станд., я только что поместил его в пространство имен станд., особенно если это - одна вещь времени. Можно просто объявить, что это статичный препятствует тому, чтобы он вызвал ошибки компоновщика, должен кто-то еще еще делать то же самое где-нибудь.

Другое решение, которое приходит на ум, должен создать обертку для станд.:: пара:

template<class A, class B>
struct pairWrapper {
  const std::pair<A,B> & x;
  pairWrapper(const std::pair<A,B> & x) : x(x) {}
}

template<class A,class B>
std::ostream & operator<<(std::ostream & stream, const pairWrapper<A,B> & pw) { ... }
2
ответ дан 30 November 2019 в 15:30
поделиться
Другие вопросы по тегам:

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