質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.78%

Python 3 Pandasでデータフレームにカラムを増やしたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 526

score 24

Pandasでサイトから引き抜いたテーブルがあるのですが、

ColumA     | ColumB | ColumC | ColumD | ColumE 
Data1  Data2  | Data3  | Data4  | Data5  |Data6

これを以下のように変更したい

Colum A | ColumB | ColumC | ColumD | ColumE | ColumF
Data1   |Data2   | Data3  | Data4  | Data5  |Data6

import pandas as pd

filename = r"c:\users\someone\desktop\BP-NET.html"
path = open(filename, 'r')

destination = r"c:\users\someone\\desktop\test.xlsx"

#Extracting the 3 tables
df1 = pd.io.html.read_html(filename, encoding='Shift JIS', attrs= {'class':'list2'})[0]
df2 = pd.io.html.read_html(filename, encoding='Shift JIS', attrs= {'class':'list2'})[1]
df3 = pd.io.html.read_html(filename, encoding='Shift JIS', attrs= {'class':'list2'})[2]

#broker names
df1_broker_name = 'broker1 (12345)'
df2_broker_name = 'broker2 (23456)'
df3_broker_name = 'broker3 (34567)'

#Adding the broker names
df = df1_broker_name + df2_broker_name + df3_broker_name

#Inserting the broker names
df1.insert(4, '販社名', df1_broker_name)
df2.insert(4, '販社名', df2_broker_name)
df3.insert(4, '販社名', df3_broker_name)

#Specifying broker codes
df1_broker_code = '12345'
df2_broker_code = '23456'
df3_broker_code = '34567'

#Adding broker codes
df = df1_broker_code + df2_broker_code + df3_broker_code

#Inserting the broker codes to column 5
df1.insert(5, '指定販売会社コード', df1_broker_code)
df2.insert(5, '指定販売会社コード', df2_broker_code)
df3.insert(5, '指定販売会社コード', df3_broker_code)

#Adding three dataframes into one
df = df1 + df2 + df3

#Concatenating the dataframes
df = pd.concat([df1, df2, df3])

# 奇数行
tmp1 = df.iloc[::2].reset_index(drop=True)
tmp1.columns = df.columns.get_level_values(0)

# 偶数行
tmp2 = df.iloc[1::2].reset_index(drop=True)
tmp2.columns = df.columns.get_level_values(1)
# 結合
df = pd.concat([tmp1, tmp2], axis=1)

print(df)
#df.to_excel(destination, sheet_name='Test')

発生している問題・エラーメッセージ

AttributeError: 'DataFrame' object has no attribute 'str'

試したこと

new = df["No状況"].str.split(" ", n = 1, expand = True) 
df["No"]= new[0] 
df["状況"]= new[1] 
df.drop(columns =["No状況"], inplace = True) 

補足情報(Excelにおとすと次のようになります)

補足:

A) 列1の'No状況'は'No'と'状況'として、別々の列に分けたいです。それに伴い、000001から000042と合計が'No'がそこに入り、当日有りと合計が'状況'に入ってほしいです。
B) テーブル1(0行目~21行目)とテーブル3(36行目~46行目)なぜかテーブル2(22行目~35行目)のファンドコードのカラムとファンド名カラムだけが逆になっています。

イメージ説明                            

ここにより詳細な情報を記載してください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • magichan

    2020/01/23 11:28

    データの形式がよくわからないので、最後の
    print(df)
    の部分を
    print(df.head(n=3))
    などと書き換えて、出力された結果をすべて質問に書き出す事はできませんでしょうか。(できたらコードブロックのマークダウンを使って書いてください)
    データで見せたくない部分は適当な値に書き直して頂いても構いません。

    キャンセル

  • SnowBallEffect

    2020/01/23 13:44

    Magichanさん、エクセルが多き過ぎて画像を添付いたしました。

    キャンセル

回答 2

checkベストアンサー

0

データがないのでよくわかりませんが、「試したとこ」の部分はこんな感じでしょうか。

import pandas
df = pandas.DataFrame([[f"Aa{i} Ab{i}" ,f"B{i}", f"C{i}"]for i in range(3)], columns=["No状況", "B", "C"])
print(df)

new_df = df["No状況"].str.split(' ', expand=True)
new_df.columns=["No", "状況"]
print(new_df)

df = pandas.concat([new_df, df], axis=1).drop('No状況', axis=1)
print(df)


df
No状況   B   C
0  Aa0 Ab0  B0  C0
1  Aa1 Ab1  B1  C1
2  Aa2 Ab2  B2  C2

new_df
No   状況
0  Aa0  Ab0
1  Aa1  Ab1
2  Aa2  Ab2

df
No   状況   B   C
0  Aa0  Ab0  B0  C0
1  Aa1  Ab1  B1  C1
2  Aa2  Ab2  B2  C2

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/01/24 15:40

    すいません、どこからdf.columns=["No状況", x,x,x,"No状況_不要",x,x] と書けばよろしいでしょうか?最後のコードが#tmp2 = df.iloc[1::2].reset_index(drop=True)
    #tmp2.columns = df.columns.get_level_values(1) なのですが、もうこの時点で2列になっています。。。

    何度もすいません。。。

    キャンセル

  • 2020/01/24 16:58

    少なくとも、str.splitを使う段階ではNo状況列は1つになっていないと問題があります。
    なので、その直前のdfの列名を確認して、不要なものを書き換えて下さい。

    キャンセル

  • 2020/01/31 11:15

    できました!

    new = df1_tmp1['No状況']

    #splitting
    df1_tmp1['No'] = new[:0]
    #splitting
    df1_tmp1['状況'] = new[:0]

    キャンセル

0

pd.concat([tmp1, tmp2], axis=1)の結果、同じ名前の列が複数できているdf['列名']の結果としてSeriesではなくDataFrameが返り、提示エラーが発生します。
そのような場合はilocでインデックスで列を指定することで回避可能です。

import pandas as pd

tmp1 = pd.DataFrame([['a','b'],['d','d']], columns=['c1','c2'])
tmp2 = pd.DataFrame([['e','f'],['g','h']], columns=['c2','c3'])
df = pd.concat([tmp1, tmp2], axis=1)
print(df)
#  c1 c2 c2 c3
#0  a  b  e  f
#1  d  d  g  h

print(df['c1'].str.split(' '))
#0    [a]
#1    [d]

# SeriesではなくDataFrameが返る
print(df['c2'])
#  c2 c2
#0  b  e
#1  d  g

# print(df['c2'].str.split(' '))
# AttributeError: 'DataFrame' object has no attribute 'str'

# 左側の「c2」列を抽出
print(df.iloc[:,1].str.split(' '))
#0    [b]
#1    [d]

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.78%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る