简体   繁体   中英

Python - load unknown data as n-dim matrix

I have a data file including the "snapshots" of an unknown boardgame, such as tictactoe/dama/chess/go..etc. But i don't know the parameters of the game, such as dimension of the board, type of pieces..etc

The easiest case is the tictactoe so lets take it as an example. Pieces and empty fields are represented as numbers (-n,-n+1.. 0, +n-1..+n.. )

Start:

  • 0 0 0
  • 0 0 0
  • 0 0 0

In this simple case each move (x,O is represented by 1 or -1, empty field is 0. ). At the end i'll have a set of 3x3 matrices separated by two empty lines.

How can i read the data into an ndim array ([length_of_game][board_width][board_length] without manually adding any information about the size of the bor/length of the game?

I know only that i have a board with unknown size, different pieces are represented by different numbers, and the snapshots represents the evolution of the game.

One way that you can do this is to parse the file line by line. Split the line by white space (assuming that the numbers in one line are separated by white space) and add the resulting list in an other list (lets call this current_game) which will hold all of the rows (lines data). When you encounter an empty line, you can add the current_game list in another list (lets call this one games), which will hold all the games.

Here is an example function which will do that:

def parse_data_file(file_path):
    games = []
    current_game = []
    with open(file_path, mode='r',) as file_reader:
        for line in file_reader:
            if len(line.strip()) == 0:
                if len(current_game) > 0:
                    # A empty new line, so the current game has finished. Add the current game to the games.
                    games.append(current_game)
                    current_game = []
            else:
                current_game.append(line.strip().split())

    return games

The function is checking if the current line length is bigger than 0, and if it is, then it is first striping it (removing any white space from the end of the line), and then splitting it by white space. You can read more about the split function here . If the line length is equal to 0, and if current_game length is larger than 0 (this check is to add current_game only once in the lists of games) it will add the list to the games list, and it will set it to new empty list.

If you want to cast the strings in the lists to integer you can use the map function when you are splitting the line. Here is the same code with casting the string to integers:

def parse_data_file(file_path):
    games = []
    current_game = []
    with open(file_path, mode='r',) as file_reader:
        for line in file_reader:
            if len(line.strip()) == 0:
                if len(current_game) > 0:
                    # A empty new line, so the current game has finished. Add the current game to the games.
                    games.append(current_game)
                    current_game = []
            else:
                current_game.append(map(lambda item: int(item), line.strip().split()))

    return games

Finally, to cast the lists in numpy ndim array you can use the array function from numpy. This solution assumes that after the last game, there will be two empty lines, but it is easy to change that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM