Полезным и гибким способом форматирования DateTimes в JavaScript является Intl.DateTimeFormat
:
var date = new Date();
var options = { year: 'numeric', month: 'short', day: '2-digit'};
var _resultDate = new Intl.DateTimeFormat('en-GB', options).format(date);
// The _resultDate is: "12 Oct 2017"
// Replace all spaces with - and then log it.
console.log(_resultDate.replace(/ /g,'-'));
Результат: "12-Oct-2017"
Форматы даты и времени могут быть настроены используя аргумент options.
Объект Intl.DateTimeFormat
- это конструктор для объектов, которые позволяют форматирование даты и времени с учетом языка.
Синтаксис
new Intl.DateTimeFormat([locales[, options]])
Intl.DateTimeFormat.call(this[, locales[, options]])
Параметры
locales
Необязательно. Строка с тегом языка BCP 47 или массив таких строк. Для общей формы и интерпретации аргумента locales см. Страницу Intl. Разрешены следующие ключи расширения Unicode:
nu
Numbering system. Possible values include: "arab", "arabext", "bali", "beng", "deva", "fullwide", "gujr", "guru", "hanidec", "khmr", "knda", "laoo", "latn", "limb", "mlym", "mong", "mymr", "orya", "tamldec", "telu", "thai", "tibt".
ca
Calendar. Possible values include: "buddhist", "chinese", "coptic", "ethioaa", "ethiopic", "gregory", "hebrew", "indian", "islamic", "islamicc", "iso8601", "japanese", "persian", "roc".
Опции
Необязательно. Объект с некоторыми или всеми из следующих свойств:
localeMatcher
Используемый алгоритм соответствия локали. Возможными значениями являются "lookup"
и "best fit"
; по умолчанию используется значение "best fit"
. Информацию об этой опции см. На странице Intl.
timeZone
Часовой пояс для использования. Единственные значения, которые должны быть реализованы, - "UTC"
; по умолчанию используется временной диапазон времени выполнения. Реализации могут также распознавать имена часовых поясов базы данных часовых поясов IANA, такие как "Asia/Shanghai"
, "Asia/Kolkata"
, "America/New_York"
.
hour12
Использовать ли 12-часовую (в отличие от 24-часового времени). Возможные значения: true
и false
; значение по умолчанию зависит от языка.
formatMatcher
Используемый алгоритм соответствия формату. Возможными значениями являются "basic"
и "best fit"
; по умолчанию используется значение "best fit"
. Для получения информации об использовании этого свойства см. Следующие параграфы.
Следующие свойства описывают компоненты даты и времени для использования в форматированном выходе и их желаемых представлениях. Реализации необходимы для поддержки, по крайней мере, следующих подмножеств:
weekday, year, month, day, hour, minute, second
weekday, year, month, day
year, month, day
year, month
month, day
hour, minute, second
hour, minute
Реализации могут поддерживать другие подмножества, и запросы будут согласовываться со всеми доступными комбинациями подмножества, чтобы найти наилучшее соответствие. Для этого согласования доступны два алгоритма и выбрано свойством formatMatcher: Полностью указанный алгоритм "basic"
и алгоритм «наилучшего соответствия», зависящий от реализации.
weekday
Представление будний день. Возможные значения: "narrow"
, "short"
, "long"
.
era
Представление эпохи. Возможные значения: "narrow"
, "short"
, "long"
.
year
Представление года. Возможные значения: "numeric"
, "2-digit"
.
month
Представление месяца. Возможные значения: "numeric"
, "2-digit"
, "narrow"
, "short"
, "long"
.
день
Представление дня. Возможные значения: "numeric"
, "2-digit"
.
hour
Представление часа. Возможные значения: "numeric"
, "2-digit"
.
минута
Представление минуты. Возможные значения: "numeric"
, "2-digit"
.
second
Представление второго. Возможные значения: "numeric"
, "2-digit"
.
timeZoneName
Представление имени часового пояса. Возможные значения: "short"
, "long"
. Значение по умолчанию для каждого свойства компонента даты и времени не определено, но если все свойства компонента не определены, то предполагается, что год, месяц и день "numeric"
.
Вот что я сделал:
Я расколол ваш файл данных в более длинный формат, а затем сгруппировал его по столбцу имен. В каждой группе я бросаю NaNs, но затем пересказываю полный набор h1 мысли h4, тем самым воссоздавая ваши NaN справа.
from io import StringIO
import pandas
def defragment(x):
values = x.dropna().values
return pandas.Series(values, index=df.columns[:len(values)])
datastring = StringIO("""\
Name h1 h2 h3 h4
A 1 nan 2 3
B nan nan 1 3
C 1 3 2 nan""")
df = pandas.read_table(datastring, sep='\s+').set_index('Name')
long_index = pandas.MultiIndex.from_product([df.index, df.columns])
print(
df.stack()
.groupby(level='Name')
.apply(defragment)
.reindex(long_index)
.unstack()
)
И вот я получаю:
h1 h2 h3 h4
A 1 2 3 NaN
B 1 3 NaN NaN
C 1 3 2 NaN
Вот как вы могли бы сделать это с помощью регулярного выражения (возможно, не рекомендуется):
pd.read_csv(StringIO(re.sub(',+',',',df.to_csv())))
Out[20]:
Name h1 h2 h3 h4
0 A 1 2 3 NaN
1 B 1 3 NaN NaN
2 C 1 3 2 NaN
Сначала сделайте функцию.
def squeeze_nan(x):
original_columns = x.index.tolist()
squeezed = x.dropna()
squeezed.index = [original_columns[n] for n in range(squeezed.count())]
return squeezed.reindex(original_columns, fill_value=np.nan)
Во-вторых, примените функцию.
df.apply(squeeze_nan, axis=1)
Вы также можете попробовать оси = 0 и. [:: - 1]
[EDIT]
@ Mxracer888 вы хотите это?
def squeeze_nan(x, hold):
if x.name not in hold:
original_columns = x.index.tolist()
squeezed = x.dropna()
squeezed.index = [original_columns[n] for n in range(squeezed.count())]
return squeezed.reindex(original_columns, fill_value=np.nan)
else:
return x
df.apply(lambda x: squeeze_nan(x, ['B']), axis=1)