🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

1回答

2282閲覧

geopandasでシェープを開いた時に属性の型を正しくしたい。

xail2222

総合スコア1508

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2021/03/09 22:43

編集2021/03/10 13:50

前提・実現したいこと

geopandasでシェープを開いた時に属性の型を正しくしたい。

試したこと

python

1import geopandas as gpd 2 3gdf=gpd.read_file(r"C:\work\sample01\result\sample4.shp") 4 5#dtypeを見ると型が正しく設定されていないようです。 6for name,dtype in zip(gdf.columns.values,gdf.dtypes): 7 print("%s %s" % (name,dtype)) 8 9#astypeすると型が変換されるみたい 10gdf=gdf.astype({'test3': float, 'column': str,'D':'datetime64[ns]'}) 11for name,dtype in zip(gdf.columns.values,gdf.dtypes): 12 print("%s %s" % (name,dtype)) 13

開いた後だとastypeで型を変換できるようなのですが
これが普通のやり方なのでしょうか。

対象のファイルは、以下のコードで作ったものです。

python

1import osgeo.ogr as ogr 2import osgeo.osr as osr 3from shapely.geometry import LineString 4 5os.environ['SHAPE_ENCODING'] = "utf-8" 6 7# shapefileドライバ 8driver = ogr.GetDriverByName("ESRI Shapefile") 9 10# Shape出力先を設定 11data_source = driver.CreateDataSource(r"C:\work\sample01\result\sample4.shp") 12 13# レイヤ作成 14layer = data_source.CreateLayer("sample4", geom_type= ogr.wkbLineString) 15 16# フィールド追加 17field_name = ogr.FieldDefn("column", ogr.OFTString) 18field_name.SetWidth(24) 19layer.CreateField(field_name) 20 21field_add=ogr.FieldDefn("Latitude", ogr.OFTReal) 22field_add.SetWidth(4) 23field_add.SetPrecision(2) 24layer.CreateField(field_add) 25 26field_add=ogr.FieldDefn("Longitude", ogr.OFTReal) 27field_add.SetWidth(6) 28field_add.SetPrecision(2) 29layer.CreateField(field_add) 30 31field_add=ogr.FieldDefn("test3", ogr.OFTReal) 32field_add.SetWidth(8) 33field_add.SetPrecision(4) 34layer.CreateField(field_add) 35 36field_add=ogr.FieldDefn("D", ogr.OFTDate) 37field_add.SetWidth(20) 38layer.CreateField(field_add) 39 40 41feature = ogr.Feature(layer.GetLayerDefn()) 42feature.SetField("column", "test") 43feature.SetField("Latitude", 2) 44feature.SetField("Longitude", 5) 45feature.SetField("D", '2017/11/12') 46 47line = ogr.CreateGeometryFromWkt('LINESTRING (30 2.5, 30 5, 0 5)') 48feature.SetGeometry(line) 49layer.CreateFeature(feature) 50 51feature = ogr.Feature(layer.GetLayerDefn()) 52feature.SetField("column", "あい") 53feature.SetField("Latitude", 3) 54feature.SetField("Longitude", 6) 55feature.SetField("D", '2017/11/14') 56 57line = ogr.CreateGeometryFromWkt('LINESTRING (1 3, 4 5, 0 5)') 58feature.SetGeometry(line) 59layer.CreateFeature(feature) 60 61feature =None 62data_source = None

違っているとわかった個所は
Dのフィールドとtest3のフィールドで
作った時は日付型と実数型だったのですが
読み込んだら共にObject型になっていました。

補足情報(FW/ツールのバージョンなど)

Python 3.9.2
geopandas 0.8.2

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

etherbeg

2021/03/10 13:30

具体的に、どう正しくない(間違っている)ですか? ご自分で作られたファイルですか、ダウンロードしたファイルですか? 他のファイルでも同じですか?
xail2222

2021/03/10 13:51

対象のファイルを作ったコードと、違っていた点を記載しました。
etherbeg

2021/03/10 14:06

ありがとうございます。何か分かりましたらまた書き込みさせていただきます。
guest

回答1

0

ベストアンサー

test3 のフィールドが Object 型になったのは、test3 のフィールドに値が設定されていないからと思われます。値が None のみの列は Object 型になります。

python

1>>> gdf = gpd.read_file("sample4.shp", encoding="utf-8") 2>>> gdf.test3 30 None 41 None 5Name: test3, dtype: object 6>>> gdf['column_none'] = None 7>>> gdf.dtypes 8column object 9Latitude float64 10Longitude float64 11test3 object 12D object 13geometry geometry 14column_none object 15dtype: object

値として np.nan を設定しておけば、値を入力しなくても、実数型が保持されます。

python

1import numpy as np 2(...) 3feature.SetField("test3", np.nan) 4(...)

python

1>>> gdf.dtypes 2column object 3Latitude float64 4Longitude float64 5test3 float64 6D object 7geometry geometry 8dtype: object 9>>> gdf.test3 100 NaN 111 NaN 12Name: test3, dtype: float64

D のフィールドが Object 型になったのは、

  1. fiona ライブラリがシェープファイルを読み込む際に、属性ファイルの Date 型を Python の str 型(正確にはその拡張型)に変換して読み込むことと、
  2. geopandas が fiona からデータを受け取って GeoDataFrame を生成する際に、スキーマのデータ型情報を参照することはせず、データをそのまま pandas.DataFrame のコンストラクタに渡す(この場合だと単なる文字列として渡される)こと、

以上2点によるものと思われます。

ドキュメントをあたったり、いくつか試してみた限りでは、GeoDataFrame として読み込んだ後に日付型に変換するしかなさそうです。

投稿2021/03/10 16:53

編集2021/03/10 16:55
etherbeg

総合スコア1195

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

xail2222

2021/03/10 21:46

回答ありがとうございます。 初めに指定できれば処理速度的に良い気がしたのですが後でするしかなささそうですね…
xail2222

2021/03/10 22:25 編集

ってかgdf.dtypesの出力でカラム名まで出るんですね
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問