Предположим, у вас есть серия 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)
Я основал один новый изящный способ решить эту проблему.
у меня есть много идей интереса когда прочитанные ответы:
я думаю, что буду использовать все это, идеи в будущем для решают различные другие проблемы.
, Но для этого случая я преуменьшил это, я могу сформулировать свой 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 );
я думаю, что этот метод является самым коротким и выразительным, чем другие.
Нет никакого стандартного способа ухаживать 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));
Я был бы точно так же, как, чтобы указать что добавление вещей к станд.:: пространство имен недопустимо согласно Стандарту C++ (см. раздел 17.4.3.1).
То, что Вы хотите, является итератором преобразования. Этот вид итератора обертывает другой итератор, вперед все методы расположения как оператор ++ и оператор ==, но переопределяет оператор* и оператор->.
Быстрый эскиз:
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 + "]";
}
...
Используя Лямбду Повышения, Вы могли попробовать что-то вроде этого. Версия, которую я имею Лямбды Повышения, это на самом деле не работает, я протестирую и зафиксирую позже.
#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 ) );
[Я удалил бы этот ответ, но я оставлю его на данный момент, в случае, если кто-то находит обсуждение интересным.]
<забастовка>, Так как это - разумное расширение библиотеки станд., я только что поместил его в пространство имен станд., особенно если это - одна вещь времени. Можно просто объявить, что это статичный препятствует тому, чтобы он вызвал ошибки компоновщика, должен кто-то еще еще делать то же самое где-нибудь.
Другое решение, которое приходит на ум, должен создать обертку для станд.:: пара:
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) { ... }