文字列の連結に関する条件を含む If ループを作成したいと考えています。 つまり、セル A1 に特定の形式のテキストが含まれている場合は、連結のみを行い、それ以外の場合はそのままにしておきます。
例: 請求書番号が CM2/0000/ のような場合は、この文字列を日付列 (月 - 年) と連結します。それ以外の場合は、請求書番号をそのままにしておきます。
サンプルデータ
サンプル データを使用して投稿を更新してください。辞書からデータフレームを作成できます。
– マイク672020 年 9 月 5 日 2:22
コード、データ、エラー メッセージは画像ではなく常にテキストとして配置してください
– フラス2020 年 9 月 5 日 16:40
必要なことを行う関数を作成し、 df.apply() を使用してそれをすべての行で実行できます。
@Boomer の回答からのサンプル データを使用します。
編集: dataframe に実際にあるものを示していませんでした。bil_date に datetime があるようですが、文字列を使用しました。これをどのように扱うかを示すために、文字列を日時に変換する必要がありました。そして今、それは必要です.str[3:].str.replace('/','-') の代わりに .strftime('%m-%y') または .dt.strftime('%m-%y') を使用します。パンダは国ごとに異なる形式で dateitm を表示するため、str(x) を使用すると、15/09/19 ではなく 2019-09-15 00:00:00 が表示されるためです。
import pandas as pd
df = pd.DataFrame({
'bill_number': ['CM2/0000/', 'CM2/0000', 'CM3/0000/', 'CM3/0000'],
'bill_date': ['15/09/19', '15/09/19', '15/09/19', '15/09/19']
})
df['bill_date'] = pd.to_datetime(df['bill_date'])
def convert(row):
if row['bill_number'].endswith('/'):
#return row['bill_number'] + row['bill_date'].str[3:].replace('/','-')
return row['bill_number'] + row['bill_date'].strftime('%m-%y')
else:
return row['bill_number']
df['bill_number'] = df.apply(convert, axis=1)
print(df)
結果:
bill_number bill_date
0 CM2/0000/09-19 15/09/19
1 CM2/0000 15/09/19
2 CM3/0000/09-19 15/09/19
3 CM3/0000 15/09/19
2 番目のアイデアは、マスクを作成することです
mask = df['bill_number'].str.endswith('/')
その後、すべての値にそれを使用します
#df.loc[mask,'bill_number'] = df[mask]['bill_number'] + df[mask]['bill_date'].str[3:].str.replace('/','-')
df.loc[mask,'bill_number'] = df[mask]['bill_number'] + df[mask]['bill_date'].dt.strftime('%m-%y')
または
#df.loc[mask,'bill_number'] = df.loc[mask,'bill_number'] + df.loc[mask,'bill_date'].str[3:].str.replace('/','-')
df.loc[mask,'bill_number'] = df.loc[mask,'bill_number'] + df.loc[mask,'bill_date'].dt.strftime('%m-%y')
左側では、値を正しく割り当てるために `[mask]['bill_number'] の代わりに .loc[mask,'bill_number'] が必要ですが、右側ではその必要がありません。
import pandas as pd
df = pd.DataFrame({
'bill_number': ['CM2/0000/', 'CM2/0000', 'CM3/0000/', 'CM3/0000'],
'bill_date': ['15/09/19', '15/09/19', '15/09/19', '15/09/19']
})
df['bill_date'] = pd.to_datetime(df['bill_date'])
mask = df['bill_number'].str.endswith('/')
#df.loc[mask,'bill_number'] = df[mask]['bill_number'] + df[mask]['bill_date'].str[3:].str.replace('/','-')
# or
#df.loc[mask,'bill_number'] = df.loc[mask,'bill_number'] + df.loc[mask,'bill_date'].str[3:].str.replace('/','-')
df.loc[mask,'bill_number'] = df[mask]['bill_number'] + df[mask]['bill_date'].dt.strftime('%m-%y')
#or
#df.loc[mask,'bill_number'] = df.loc[mask,'bill_number'] + df.loc[mask,'bill_date'].dt.strftime('%m-%y')
print(df)
3 番目のアイデアは、numpy.where() を使用することです
import pandas as pd
import numpy as np
df = pd.DataFrame({
'bill_number': ['CM2/0000/', 'CM2/0000', 'CM3/0000/', 'CM3/0000'],
'bill_date': ['15/09/19', '15/09/19', '15/09/19', '15/09/19']
})
df['bill_date'] = pd.to_datetime(df['bill_date'])
df['bill_number'] = np.where(
df['bill_number'].str.endswith('/'),
#df['bill_number'] + df['bill_date'].str[3:].str.replace('/','-'),
df['bill_number'] + df['bill_date'].dt.strftime('%m-%y'),
df['bill_number'])
print(df)
3
これらの回答のうち 2 つを試しましたが、def (row) の回答では次のエラーが発生しました: TypeError: ("'Timestamp' object is not subscriptable", 'occurred atindex 0' ;) そして、np.where アプローチを試してみたところ、次のエラーが発生しました: AttributeError: Can Only use .str accessor with string names, that use np.object_ dtype in pandas
– サナ・シャー2020 年 9 月 5 日 16:15
問題はそれです質問に実際のデータが示されていませんでした。エラーは、列 bill_date にタイムスタンプがあることを示していますが、文字列しかありません。コードをテストするには、文字列を日時に変換する必要があります。df[' の代わりに row['bill_date'].strftime('%m-%y') が必要のようです。 ;請求日'].str[3:].str.replace('/','-')
– フラス2020 年 9 月 5 日 16:56
回答の例を変更しました。文字列の代わりに日時を使用するようになりました。
– フラス2020 年 9 月 5 日 17:11
おそらくこれはあなたにとってうまくいくでしょう。 @Mike67 が述べていたようなデータサンプルがあればいいですね。しかし、あなたの情報に基づいて、これが私が思いついたものです。かさばりますが、機能します。きっと他の誰かがもっと派手なバージョンを作ってくれると思います。
import pandas as pd
from pandas import DataFrame, Series
dat = {'num': ['CM2/0000/','CM2/0000', 'CM3/0000/', 'CM3/0000',],
'date': ['15/09/19','15/09/19','15/09/19','15/09/19']}
df = pd.DataFrame(dat)
df['date'] = df['date'].map(lambda x: str(x)[3:])
df['date'] = df['date'].str.replace('/','-')
for cols in df.columns:
df.loc[df['num'].str.endswith('/'), cols] = df['num'] + df['date']
print(df)
Results:
num date
0 CM2/0000/09-19 09-19
1 CM2/0000 09-19
2 CM3/0000/09-19 09-19
3 CM3/0000 09-19